Linux-文本操作AWK和SED

AWK

awk是一个强大的文本分析工具,简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息 。
awk处理过程: 依次对每一行进行处理,然后输出。

$0 表示整个当前行
$1 每行第一个字段
NF 字段数量变量
NR 每行的记录号,多文件记录递增
FNR 与NR类似,不过多文件记录不递增,每个文件都从1开始
\t 制表符
\n 换行符
FS BEGIN时定义分隔符
RS 输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)
~ 匹配,与"等号"相比不是精确比较
!~ 不匹配,不精确比较
== 等于,必须全部相等,精确比较
!= 不等于,精确比较
&& 逻辑与
|| 逻辑或
“+” 匹配时表示1个或1个以上
/[0-9][0-9]+/ 两个或两个以上数字
/[0-9][0-9]*/ 一个或一个以上数字
FILENAME 文件名

特殊模式

BEGIN 模式:是指 awk 将在读取任何输入行之前立即执行 BEGIN 中指定的动作。
END 模式:是指 awk 将在它正式退出前执行 END 中指定的动作。

含有这些特殊模式的 awk 命令脚本的执行流程如下:
1.当在脚本中使用了 BEGIN 模式,则 BEGIN 中所有的动作都会在读取任何输入行之前执行。
2.然后,读入一个输入行并解析成不同的段。
3.接下来,每一条指定的非特殊模式都会和输入行进行比较匹配,当匹配成功后,就会执行模式对应的动作。对所有你指定的模式重复此执行该步骤。
4.再接下来,对于所有输入行重复执行步骤 2 和 步骤 3。
5.当读取并处理完所有输入行后,假如你指定了END模式,那么将会执行相应的动作。

常用操作

awk  -F"," '{print $1,$3,$6}' //输出字段1,3,6,以逗号作为分隔符。
awk  -F"," '{if($5>200) print}' //输出第5列大于200的所有数据
awk -F"," '{print NF}'  a.txt  //显示每行有多少字段
awk -F"," 'NF==4 {print }'  a.txt //显示只有4个字段的行
awk -F: '{print NR}'  a.txt  //显示多少行
awk -F: 'NR==5{print}'  a.txt  //显示第5行
awk -F: 'NR==5 || NR==6{print}'  a.txt	//显示第5行和第6行

复杂操作

[h_chenliling@vm6-sj1-pro-had-32-107 ~]$ cat test.txt 
001,20
002,40
004,30
003,30
005,5
001,90
002,34
004,34
002,76

对第二列求和
[h_chenliling@vm6-sj1-pro-had-32-107 ~]$ cat test.txt  |awk -F"," 'BEGIN{sum=0} {sum+=$2} END{print sum}'
359

分组统计
[h_chenliling@vm6-sj1-pro-had-32-107 ~]$ cat test.txt |awk -F"," '{x[$1]+=$2}  END{for(i in x) print i,x[i]}'
002 150
003 30
004 64
005 5
001 110

分组求平均
[h_chenliling@vm6-sj1-pro-had-32-107 ~]$ cat test.txt |awk -F"," '{x[$1]+=$2;count[$1]++}  END{for(i in x) print i,x[i],x[i]/count[$1]}'
002 150 50
003 30 10
004 64 21.3333
005 5 1.66667
001 110 36.6667


格式化
[h_chenliling@vm6-sj1-pro-had-32-107 ~]$ cat test.txt |awk -F"," '{x[$1]+=$2}  END{for(i in x) printf("%s,%d\n",i,x[i])}'
002,150
003,30
004,64
005,5
001,110

求最大值
[h_chenliling@vm6-sj1-pro-had-32-107 ~]$ cat test.txt |awk -F"," 'BEGIN{max=0}{if($2>max) max=$2}  END{print max}'
90


分组求最大值
[h_chenliling@vm6-sj1-pro-had-32-107 ~]$ cat test.txt |awk -F"," '{if($2>x[$1]) {x[$1]=$2}} END{for (i in x) print i,x[i]}'
002 76
003 30
004 34
005 5
001 90

SED

Stream Editor文本流编辑,sed是一个“非交互式的”面向字符流的编辑器。可以不对原文件改动,把整个文件输入到屏幕,可以把只匹配到模式的内容输入到屏幕上。还可以对原文件改动,但是不会再屏幕上返回结果

常用选项:

-n∶取消默认的输出,使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN的资料一般都会被列出到屏幕上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来
-e∶进行多项编辑,即对输入行应用多条sed命令时使用. 直接在指令列模式上进行 sed 的动作编辑
-f∶指定sed脚本的文件名. 直接将 sed 的动作写在一个档案内, -f filename 则可以执行 filename 内的sed 动作
-r∶sed 的动作支援的是延伸型正则表达式的语法。(预设是基础正则表达式语法)
-i∶直接修改读取的文件内容,而不是由屏幕输出

常用命令:

a ∶ 新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)
c ∶ 取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行
d ∶ 删除,因为是删除,所以 d 后面通常不接任何内容
i ∶ 插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行)
p∶ 列印,亦即将某个选择的资料印出。通常 p 会与参数 sed -n 一起用
s∶ 取代,可以直接进行替换的工作。通常这个 s 的动作可以搭配正则表达式。例如 1,20s/old/new/g

定址
定址用于决定对哪些行进行编辑。如果没有指定地址,sed将处理输入文件的所有行。地址的形式可以是数字、正则表达式、或二者的结合。地址是逗号分隔的,那么需要处理的地址是这两行之间的范围(包括这两行在内)。
地址是一个数字

常用操作

显示文件20到30行数据
sed -n '20,21p' a.txt

删除文件20到30行数据
sed -n '20,21d' a.txt

删除包含"a"的行到包含"b"的行之间的行
sed '/a/,/b/d' a.txt

删除包含"a"的行到第十行的内容
sed '/a/,10d' a.txt

在第10行后面增加字符串“Hello World”
sed '10a   Hello World ' a.txt

在第11行和100行之间增加字符串“Hello World”
sed '10,100a Hello World ' a.txt

在文件末尾增加“Hello World ”,直接修改源文件
sed -i '$a Hello World'  a.txt

从第10行到100行全部用“Hello World ” 替换
sed '10,100c Hello World ' a.txt

你可能感兴趣的:(Linux/Ubuntu)