GREP、SED、AWK、TR、SORT、UNIQ的一些用法

时间:2022-10-23 16:05:38
GREP、SED、AWK、TR、SORT、UNIQ的一些用法
一、将当前目录下(包括子目录)的以.shell结尾的普通文件全部重命名为.sh结尾

view plaincopy to clipboardprint?
01.for i in `find ./ -name '*.shell' -type f `; do mv -f $i `echo $i | sed 's/shell$/sh/'`; done   
02.for i in `find ./ -name '*.shell' -type f` ; do (rename shell sh `echo $i`) ; done  
for i in `find ./ -name '*.shell' -type f `; do mv -f $i `echo $i | sed 's/shell$/sh/'`; done
for i in `find ./ -name '*.shell' -type f` ; do (rename shell sh `echo $i`) ; done

 

二、计数、分类汇总、求平均和排序、最大最小值

被操作文件内容(共3列,以空格分配)

2010-12-1 291 239
2010-12-1 163 177
2010-12-1 240 269
2010-12-1 234 252
2010-12-2 159 157
2010-12-2 203 201
2010-12-2 329 357
2010-12-2 296 224
2010-12-2 229 219

统计第一列每个日期出现的次数

view plaincopy to clipboardprint?
01.awk ' {++S[$1]} END {for(a in S) print a, S[a]}' file   
awk ' {++S[$1]} END {for(a in S) print a, S[a]}' file

 

结果如下:

2010-12-1 4
2010-12-2 5

根据第一列日期,对第二列进行分类汇总

view plaincopy to clipboardprint?
01.awk '{a[$1]++;s2[$1]+=$2} END {for (i in a)  print i,s2[i]}' file   
awk '{a[$1]++;s2[$1]+=$2} END {for (i in a)  print i,s2[i]}' file

 

结果如下:

2010-12-1 928
2010-12-2 1216

根据前面二次的结果求其平均值,并且由高到低排序

view plaincopy to clipboardprint?
01.awk '{a[$1]++;s2[$1]+=$3} END {for (i in a)  print i,a[i],s2[i],s2[i]/a[i]}' ttt \   
02. | sort -r  -n -t ' ' -k 4  
awk '{a[$1]++;s2[$1]+=$3} END {for (i in a)  print i,a[i],s2[i],s2[i]/a[i]}' ttt \
 | sort -r  -n -t ' ' -k 4

结果如下:

2009-4-3 5 1216 243.2
2009-4-2 4 928 232

分类求最大值和最小值

被操作文件内容:

2009-11-01 291
2009-11-01 163
2009-11-01 240
2009-11-01 234
2009-11-02 159
2009-11-02 203
2009-11-02 329
2009-11-02 296
2009-11-02 229
2009-11-03 -39
2009-11-03 -426
2009-11-03 -139

view plaincopy to clipboardprint?
01.awk '{if (max2[$1]=="") { max2[$1]=$2 } if (min2[$1]=="") { min2[$1]=$2 } \   
02.a[$1]++;max2[$1]=($2>max2[$1]?$2:max2[$1]);min2[$1]=($2<min2[$1]?$2:min2[$1])} END \   
03. {printf "%10s\t%6s\t%6s\n","当天的日期","最大值","最小值" ; \   
04.for (i in a) printf "%10s\t%6s\t%6s\n",i,max2[i],min2[i]}' file  
awk '{if (max2[$1]=="") { max2[$1]=$2 } if (min2[$1]=="") { min2[$1]=$2 } \
a[$1]++;max2[$1]=($2>max2[$1]?$2:max2[$1]);min2[$1]=($2<min2[$1]?$2:min2[$1])} END \
 {printf "%10s\t%6s\t%6s\n","当天的日期","最大值","最小值" ; \
for (i in a) printf "%10s\t%6s\t%6s\n",i,max2[i],min2[i]}' file

结果如下:



三、将行首首次出现22的所在行的行号和第二个字段内容显示出来(分隔符为:,二种方法)

被操作文件内容

11:dfs:bcd
112234324234:dsfsdf:234
112432423423:sdf:94234
11234:sdf:bbbb
222222:abcd:dfsd
2234234:dfd:fdf
2234343:dfsf:324
331:sdfdsf:bcdfd
332:asfds:dfdsf
3333333333:sfddsf:dsfsdfsd
33435:dsfsdf:sfdsf
44::234
4456:sdfds:dsf

view plaincopy to clipboardprint?
01.grep -n ^22 file | head -n 1 | cut -d ':' -f 1,3   
02.grep -n ^22 file | head -n 1 | awk 'BEGIN {FS=":"} {print $1 ":" $3}'   
grep -n ^22 file | head -n 1 | cut -d ':' -f 1,3
grep -n ^22 file | head -n 1 | awk 'BEGIN {FS=":"} {print $1 ":" $3}'

 

结果如下:

5:abcd

四、将首次出现“222”到再次出现“222”之间的内容显示出来

被操作文件内容

11
112234324234
112432423423
11234
222222
2234234
2234343
331
2222
332
3333333333
33435
44
4456

view plaincopy to clipboardprint?
01.awk '/222/{print;while(getline line){if(line ~ /222/){break};print line}}' file  
awk '/222/{print;while(getline line){if(line ~ /222/){break};print line}}' file

结果如下:

222222
2234234
2234343
331

五、显示指定行(第一次在行首出现222的行)到首行或末行之间的内容

被操作文件内容

11
112234324234
112432423423
11234
222222
2234234
2234343
331
2222
332
3333333333
33435
44
4456

 
view plaincopy to clipboardprint?
01.awk 'NR==1 {print;while(getline line){if(line ~ /222/){break};print line}}' file   
02.awk '/222/{while(getline line) print line}' file  
awk 'NR==1 {print;while(getline line){if(line ~ /222/){break};print line}}' file
awk '/222/{while(getline line) print line}' file

二个命令的操作结果分别如下:

11
112234324234
112432423423
11234

2234234
2234343
331
2222
332
3333333333
33435
44
4456

六、查找在韦伯时间之前且是后台开发的人员名字

a文件

10月13日 12:00 张三
10月15日 12:30 韩七
9月1日 1:3 王二
10月14日 12:30 马五
1月12日 11:3 王四
10月14日 12:00 李四
10月14日 13:30 韦伯

b文件
韩七 后台开发  
张三 后台开发  
王六 游戏开发  
李四 后台开发  
马五 客户端开发  
韦伯 后台开发  
陈八 游戏开发
王二 后台开发
王四 游戏开发

 
view plaincopy to clipboardprint?
01.for i in `sort -n a | \   
02.awk 'NR==1 {print;while(getline line){if(line ~ /韦伯/){break};print line}}'  | \   
03.awk '{print $3}'` ; do (grep $i b | grep '后台开发' | cut -d ' ' -f 1) ; done  
for i in `sort -n a | \
awk 'NR==1 {print;while(getline line){if(line ~ /韦伯/){break};print line}}'  | \
awk '{print $3}'` ; do (grep $i b | grep '后台开发' | cut -d ' ' -f 1) ; done

结果如下:

王二
张三
李四

七、提取电话号码和邮件地址

提取手机号码(假定手机号码为11个数字)

view plaincopy to clipboardprint?
01.grep -o '\b[0-9]\{11\}\b' file | sort | uniq  
grep -o '\b[0-9]\{11\}\b' file | sort | uniq

提取固定电话号码(假定由3部分组成,使用-分割,第一部分为区号,3-5为数字,第二部分为7-8位数字的电话号码,第三部分为可能存在的分机,1个数字以上)

view plaincopy to clipboardprint?
01.grep -E  -o '\b[0-9]{3,5}-[0-9]{7,8}\b|\b[0-9]{3,5}-[0-9]{7,8}-[0-9]{1,}\b'  file | sort | uniq  
grep -E  -o '\b[0-9]{3,5}-[0-9]{7,8}\b|\b[0-9]{3,5}-[0-9]{7,8}-[0-9]{1,}\b'  file | sort | uniq

提取邮件地址(假定邮件地址首字符范围在52个大小写英文字母和10个阿拉伯数字之内,其后字符范围加上3个字符“-_.”,整个邮件地址被“@”“.”分割为3部分,每部分至少包含一个字符)

view plaincopy to clipboardprint?
01.grep -o '[a-zA-Z0-9][a-zA-Z0-9_-.]\{0,\}@[a-zA-Z0-9_-.]\{1,\}\.[a-zA-Z0-9_-.]\{1,\}' file | sort | uniq  
grep -o '[a-zA-Z0-9][a-zA-Z0-9_-.]\{0,\}@[a-zA-Z0-9_-.]\{1,\}\.[a-zA-Z0-9_-.]\{1,\}' file | sort | uniq

八、从文件中删除所有空行的几种方法

view plaincopy to clipboardprint?
01.cat file | tr -s '\n'  
02.grep -v '^$' file   
03.sed '/^$/d'  file   
04.sed -n '/./p' file   
05.awk '/./ {print}' file   
06.for i in $(cat file);do echo $i;done  
cat file | tr -s '\n'
grep -v '^$' file
sed '/^$/d'  file
sed -n '/./p' file
awk '/./ {print}' file
for i in $(cat file);do echo $i;done
 

将连续空行变为1行

view plaincopy to clipboardprint?
01.sed -e '/^$/{$!N;/^\n$/D}' file   
02.cat -s file  
sed -e '/^$/{$!N;/^\n$/D}' file
cat -s file

九、找出所有位数一样的数字 和 将所有数字倒序

被操作文件内容

234
2342
23
234
2342
88
999999
23
555
2394

view plaincopy to clipboardprint?
01.for i in $(seq 0 9); do grep "^$i\{2,\}" file; done  
for i in $(seq 0 9); do grep "^$i\{2,\}" file; done  

结果如下:

555
88
999999

view plaincopy to clipboardprint?
01.for i in `cat file` ; do  echo $i | rev ; done  
for i in `cat file` ; do  echo $i | rev ; done

结果如下:

432
2432
32
432
2432
88
999999
32
555
4932

十、拓扑排序

被操作文件内容

t3 z2 u4
u4 b7
a3 z2
u9 x5 t3 t6 c6
c6 u4
b7 c4
x5 t6

以空格为分隔符,每一个均代表一个文件,第一个文件依赖于后面的一个或者多个文件,需要对这些文件进行排序,被依赖的排在前面,比如在
t3 z2 u4
u4 b7
排序可以是
b7
z2
u4
t3

只要保证z2、u4在t3前面,b7在u4前面

view plaincopy to clipboardprint?
01.cat file | while read i j ; do for j2 in $j ; do echo $i $j2 ; done ; done | tsort  | tac  
cat file | while read i j ; do for j2 in $j ; do echo $i $j2 ; done ; done | tsort  | tac

结果是

c4
b7
t6
z2
u4
x5
t3
c6
u9
a3

注:第一个管道后的循环是将原来可能的在同一行上依赖多个文件变成一行只依赖一个,即

t3 z2 u4

变成

t3 z2

t3 u4

十一、合并sql语句

被操作文件内容

[2005/02/18 13:44:23 B0099S05] SELECT a,
|| b,
|| from dual;
[2005/02/18 13:44:23 B0099S05] UPDATE MATERIAL T
|| SET T.CDELDATE = '20050216'
aa ||fsdfs
[2005/02/18 13:44:23 B0099S05] DELETE * from MATERIAL;
aaaaaaaaaaa
|| bbbbbbbbbb
[2005/02/18 13:44:23 B0099S06] SELECT * from MATERIAL LIMIT 1;
|| bbbbbbbbbb
PL/SQL over!。

如果某一行包含字符串‘B0099S05’,则搜索下面所有行首中包含‘||’的连续行,将‘||’删除,本行与上一行拼接。

view plaincopy to clipboardprint?
01.sed -e ':a;/B0099S05/{N;s/\n||//};ta;P;D' file  
sed -e ':a;/B0099S05/{N;s/\n||//};ta;P;D' file

首先定义了一个命名为a的标签,然后去逐行搜索‘B0099S05’,如果找到,再在下一行(N的作用)进行替换(将换行符和||删除掉),如果成功执行替换,则跳转到标签a处继续执行(ta的作用),P和D的作用如下:

P  打印当前模式空间中第一行。
D  删除当前模式空间中第一行。开始新的循环,但是如果在模式空间中仍然有数据,那么跳过读取输入。

执行结果如下:

[2005/02/18 13:44:23 B0099S05] SELECT a, b, from dual;
[2005/02/18 13:44:23 B0099S05] UPDATE MATERIAL T  SET T.CDELDATE = '20050216'
aa ||fsdfs
[2005/02/18 13:44:23 B0099S05] DELETE * from MATERIAL;
aaaaaaaaaaa
|| bbbbbbbbbb
[2005/02/18 13:44:23 B0099S06] SELECT * from MATERIAL LIMIT 1;
|| bbbbbbbbbb
PL/SQL over!。

十二、货币输出

view plaincopy to clipboardprint?
01.echo 1234567890 | sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta;s/^/¥\ /'   
echo 1234567890 | sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta;s/^/¥\ /'  

执行结果:

¥ 1,234,567,890

十三、循环替换字符串

view plaincopy to clipboardprint?
01.sed -i "s/abc/def/g" `grep 'abcdef' -rl .`  
sed -i "s/abc/def/g" `grep 'abcdef' -rl .`

在当前目录及其子目录下搜索含有“abcdef”的文件,并将其中的abc替换成def。