您的位置:首页 > 运维架构 > Shell

shell 小脚本

2015-09-09 09:48 549 查看
使用awk命令将如下两份文件中名字相同的两行合并起来
A文件:
韩海林 21岁
海林韩 23岁
韩林海 22岁
林海韩 24岁
B文件:
韩林海 男
海林韩 男
韩海林 男
林海韩 男
输出效果:
韩海林 21岁 男

_________________________________________________

#! /bin/bash

A=`sed s/[[:space:]]/:/g A`
B=`sed s/[[:space:]]/:/g B`

for i in $A
do
getname=`echo $i | awk -F ':' '{print $1}'`
if [ "$getname" == "韩海林" ]
then
AM=$getname
AM1=`echo $i | awk -F ':' '{print $2}'`
fi
done
for j in $B
do
getbname=`echo $j | awk -F ':' '{print $1}'`
if [ "$getbname" == "韩海林" ]
then
BM=`echo $j | awk -F ':' '{print $2}'`
fi
done

echo $AM $AM1 $BM

-----------------------------------------------------

#! /bin/bash

`sort -n /tmp/A | awk '{print $1}' | uniq > /tmp/id.txt`

for id in `cat /tmp/id.txt`
do
echo "$id"
awk -v id2=$id '$1==id2 {print $2}' /tmp/A /tmp/B #-v的用法,以及awk可以直接处理两个文件的内容

done

-----------------------------------------------------
awk 中使用外部shell变量

如:
A=44
echo "ABCD" | awk -v GET_A=$A ’{print GET_A}’

说明:-v选项用于定义参数,这里表示将变量A的值赋予GET_A。有多少个变量需要赋值,就需要多少个-v选项。与之等价的:

应用于脚本中:
#! /bin/bash

sort -n filename |awk -F ':' '{print $1}'|uniq >id.txt
for id in `cat id.txt`; do
echo "[$id]"
awk -v id2=$id -F ':' '$1==id2 {print $2}' filename // 另外的方式为: awk -F ':' '$1=="'id2'" {print $2}' filename
done

附件:
cat filename
1111111:13443253456
2222222:13211222122
1111111:13643543544
3333333:12341243123
2222222:12123123123

运行脚本后结果为:
[1111111]
13443253456
13643543544
[2222222]
13211222122
12123123123
[3333333]
12341243123

----------------------------------------------------------
NR,表示awk开始执行程序后所读取的数据行数.

FNR,与NR功用类似,不同的是awk每打开一个新文件,FNR便从0重新累计.

下面看两个例子:

1,对于单个文件NR 和FNR 的 输出结果一样的 :

# awk '{print NR,$0}' file1
1 a b c d
2 a b d c
3 a c b d

#awk '{print FNR,$0}' file1
1 a b c d
2 a b d c
3 a c b d

2,但是对于多个文件 (NR对两个文件的操作是一直不断增加)

# awk '{print NR,$0}' file1 file2
1 a b c d
2 a b d c
3 a c b d
4 aa bb cc dd
5 aa bb dd cc
6 aa cc bb dd

# awk '{print FNR,$0}' file1 file2 (FNR是每个文件重新读取的行号)
1 a b c d
2 a b d c
3 a c b d
1 aa bb cc dd
2 aa bb dd cc
3 aa cc bb dd

在看一个例子关于NR和FNR的典型应用:

案例一、现在有两个文件格式如下:

#cat account
张三|000001
李四|000002
#cat cdr
000001|10
000001|20
000002|30
000002|15

想要得到的结果是将用户名,帐号和金额在同一行打印出来,如下:

张三|000001|10
张三|000001|20
李四|000002|30
李四|000002|15

执行如下代码

#awk -F \| 'NR==FNR{a[$2]=$0;next}{print a[$1]"|"$2}' account cdr

注释:

由NR==FNR为真时,判断当前读入的是第一个文件account,然后使用{a[$2]=$0;next}循环将account文件的每行记录都存入数组a,并使用$2第2个字段作为下标引用.

由NR==FNR为假时,判断当前读入了第二个文件cdr,然后跳过{a[$2]=$0;next},对第二个文件cdr的每一行都无条件执行{print a[$1]"|"$2},此时变量$1为第二个文件的第一个字段,与读入第一个文件时,采用第一个文件第二个字段$2为数组下标相同.因此可以在此使用a[$1]引用数组。

案例二、我有这样的需求,需要把两个文件中,第一列相同的行合并到同一行中。举个例子,有两个文件,内容如下
cat 1.txt
1 aa
2 bb
3 ee
4 ss

cat 2.txt
1 ab
2 cd
3 ad
4 bd
5 de

合并后的结果为:

1 ab aa
2 cd bb
3 ad ee
4 bd ss
5 de

实现的命令为:
awk 'NR==FNR{a[$1]=$2}NR>FNR{print $0,a[$1]}' 1.txt 2.txt

-------------------------------------------------------------------------
sed在文件中某一行最后添加一个数字
sed 's/\(^a.*\)/\1 12/' test

#cat test
askdj
aslkd aslkdjf3e
skdjfsdfj
sdkfjk
fsdkfjksdjfkjsdf
12sdfesdf
aslkdjfkasdjf asdlfkjaskdfj

#sed 's/\(^a.*\)/\1 12/' test

askdj 12
aslkd aslkdjf3e 12
skdjfsdfj
sdkfjk
fsdkfjksdjfkjsdf
12sdfesdf
aslkdjfkasdjf asdlfkjaskdfj 12

------------------------------------------------------------------------

sed中,使用\u表示大写,\l表示小写

1. 把每个单词的第一个小写字母变大写:
sed 's/\b[a-z]/\u&/g' filename

2. 把所有小写变大写:
sed 's/[a-z]/\u&/g' filename

3. 大写变小写:
sed 's/[A-Z]/\l&/g' filename

------------------------------------------------------------------------
有一份电话薄文本文件file.txt,格式如下
BILL 13800000000
TOM 13800000001
ABLE 13800000000
TOM 13800000003

要求:人名和电话均可能重复(多对多),找到出现次数最多的电话号码,并列出对于的所以人名。

#! /bin/bash
tel=`cat file.txt | awk '{print $2}' | sort -n | uniq | head -1`
echo $tel
cat file.txt | awk '{if($2=="13800000000")print $1}'
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  shell 小脚本1