1. gawk/awk文本处理工具
批量kill进程:ps -ef|grep Test|grep -V “grep”|awk ‘{print $2}’|xargs kill -9
-F/FS 指定分割符,不指定则为空格。
awk -F : ‘{print $2}’ /etc/passwd:指定“:”为分隔符,并打印出第2列数据。
awk ‘BEGIN {print ‘This is head.’};{FS=":" ; print $1};END {print ‘This is tail.’}’ /etc/passwd :BEGIN和END命令分别在最前面和最后面仅执行一次。也可以将‘BEGIN {print ‘This is head.’};{FS=":" ; print $1};END {print 'This is tail.’}'内容写进一个文件中(script.awk),然后通过-f参数从文件中读取,awk -f script.awk /etc/passwd,这样可以将命令简洁化。
(也可搭配正则表达式一起使用,完成更加强大的功能)
其他参数:
OFS: 文件输出时的列分隔符
NF:数据记录中有多少列,$NF : 取最后一列,$(NF-n) : 取倒数第几列
NR:已处理的输入记录有多少行
FNR :当前文件读了多少行,常用于多文件操作时
结构化命令使用:
awk ‘{if(NR>5) print NR ;else print “smaller”}’ /etc/passwd :如果读取到第5行后,则打印行号,否则打印smaller。
awk ‘{i=1 while(i<5 && NR<5) print NR,i=i+1}’ /etc/passwd :当i和NR都小于5时,打印NR的值。
还有do while和for循环结构化命令,语法结构和java一致。
格式化打印:
使用printf语句,语法和C语言一致。
printf “formatstring”,var1,var2,……
formatstring格式:%[modifier]control-letter,其中control-letter可选字符如下:
控制字母 | 描 述 |
---|---|
c | 将一个数作为ASCII字符显示 |
d | 显示一个整数值 |
i | 显示一个整数值,与d一样 |
e | 用科学计数法显示一个数 |
f | 显示一个浮点值 |
o | 显示一个八进制值 |
s | 显示一个文本字符串 |
x | 显示一个十六进制值 |
X | 显示一个十六进制值,但用大写字母A~F |
awk “FS=”:" {if(NR>5) printf “%-7d %s \n”,NR,$1;else print “smaller”}’ /etc/passwd:使用:分隔符,当NR大于5时,打印NR和$1的值,且NR长度至多7个字符并且左对齐。
%7.2f:浮点数其中包含2位小数。
awk -v i=1.223 “FS=”:" {if(NR>5) {i=i+1000;printf “%-7.2f %s \n”,i,$1} else print “smaller”}’ /etc/passwd:自定义参数i,打印格式为%-7.2f。
注意:对于命令行较长的命令,建议都书写在一个文件中,使用-f参数读取。
2. sed文本处理工具
强大的数据处理工具。处理后的结果仅输出到STDOUT,并不会修改原始文件内容。
可以替换文本,删除文本,插入文本,匹配字符串等
替换文本:
sed -n ‘s/test1/test2/p’ date,txt
从date.txt中读取数据,匹配每行中的test1字符串,并替换成test2。最后的p是打印原始和结果内容。
-n 和 p结合使用,可以实现只打印结果。
同时还可以将结果写入一个文件中:sed -n ‘s/test1/test2/w result.txt’ date.txt
g是将匹配到的文本替换后打印全部内容。
定位替换:
sed ‘2s/test1/test2/’ date.txt,替换第2行中匹配到的内容;
sed ‘2,3s/test1/test2/’ date.txt,替换2-3行间的内容;
sed ‘2,$s/test1/test2/’ date.txt,从第2行开始后的全部内容都被匹配替换;
sed -n ‘/content/s/test1/test2/p’ date.txt,匹配content所在的行,并替换其中的test1为test2;
sed -n ‘/content1/,/content2/s/test1/tste2/p’ date.txt,使用两个模式content1、content2模式匹配内容,然后对匹配出来的内容把其中的test1替换成test2。
sed -n ‘/begin/{n;s/test1/test2/p}’ date.txt,结合next命令,匹配begin后定位到下一行,并替换该行的test1为test2;
sed -n ‘N;s/test1\ntest1_2/test2\ntest2_2/p’ date.txt,对于需要匹配的字符串不在一行的情况,可以使用N(多行版本的next命令)来匹配。
注意:但其中存在一个问题,因为N命令会将当前行和下一行读入到模式空间中,对于最后一行是没有下一行的,如果需要匹配的内容刚好是在最后一行中出现,则需要结合单行匹配一起使用:sed -n ‘s/test1 test1_2/test2 test2_2/p;N;s/test1\ntest1_2/test2\ntest2_2/p’ date.txt;并且需要放在多行匹配的前面。
(n和N命令也可结合d、i、a使用)
删除文本:
sed ‘/test1/d’ date.txt 删除test1的那行数据
sed ‘2d’ date.txt 删除第2行数据
sed '2,4d’date.txt 删除2-4行的数据
sed '2,$d’date.txt 删除第2行后全部的数据
插入文本:
sed ‘i\content’:默认在最前面插入内容
sed ‘a\content’:默认是最后面插入内容
sed ‘3i\content’:在第3行前面插入内容
sed ‘3a\content’:在第3行后面插入内容
3.搭配正则表达式使用:
*:匹配0次,1次,多次
?:匹配0次,1次
+:匹配1次,多次
.:匹配一个字符
^:锁定在行首
$:锁定在行尾
{m}:准确出现m次
{m,n}:至少m次,至多n次
[]:字符组
[^]:排除性字符组
其中? + {},sed工具不能识别,gawk/awk可以识别,主要是因为使用的正则引擎不一样。另外gawk/awk使用{}时,还需要加上参数–re–interval。
gawk/awk例子:
验证电话号码。正确的电话号码形式有如下几种:
(123)456-7890
(123) 456-7890
123-456-7890
123.456.7890
有4种可能。
首先从最左边开始分析该4种形式,(左括号可出现1次或不出现,所以对应可以使用?匹配:^\(?
。
然后是数字0-9出现了3次,可以使用[0-9]{3}
来匹配。
然后是)右括号可出现1次或不出现:\)?
。
紧接着是分隔符可以是(空、空格、-、.),所以使用(| |-|\.)
匹配。
按照以上方法,总的来说需要匹配该4类电话号码的正则表达式可如下书写:
^\(?[0-9]{3}\)?(| |-|\.)[0-9]{3}(-|\.)[0-9]{4}
所以从telephone.txt进行匹配的gawk命令如下:
gawk --re-interval '^\(?[0-9]{3}\)?(| |-|\.)[0-9]{3}(-|\.)[0-9]{4}' telephone.txt