1. awk:文本和数据处理工具
awk擅长于对数据进行分析并生成报告,简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
使用方法:awk '{pattern + action}' {filenames}
其中pattern 表示awk 在数据中查找的内容,而action是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。pattern就是要表示的正则表达式,用斜杠括起来。准备实例操作文件:netstat -t >> netstat.txt
1.1 打印输出:
print,格式化打印输出:printf
- awk '{print$1, $4}' netstat.txt
- awk '{printf "%-8s %-8s %-8s %-18s %-22s %-15s\n",$1,$2,$3,$4,$5,$6}' netstat.txt
1.2 过滤记录:
- awk '$3==0 && $6=="LISTEN"' netstat.txt
其中的“==”为比较运算符。其他比较运算符:!=,>, <, >=, <=
- awk '$3>0 {print $0}' netstat.txt
加入表头:内建变量NR
- awk '$3==0 && $6=="LISTEN" || NR==1 ' netstat.txt
再加上格式化输出
- awk '$3 ==0 && $6=="LISTEN" || NR==1 {printf "%-20s %-20s %s\n",$4,$5,$6}' netstat.txt
ps:awk的内建变量
- $0 当前记录(这个变量中存放着整个行的内容)
- $1~$n 当前记录的第n个字段,字段间由FS分隔
- FS 输入字段分隔符默认是空格或Tab
- NF 当前记录中的字段个数,就是有多少列
- NR 已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中。
- FNR 当前记录数,与NR不同的是,这个值会是各个文件自己的行号
- RS 输入的记录分隔符,默认为换行符
- OFS 输出字段分隔符,默认也是空格
- ORS 输出的记录分隔符,默认为换行符
- FILENAME 当前输入文件的名字
输出行号:
- awk '$3 ==0 && $6=="ESTABLISHED"|| NR==1 {printf "%02s %s %-20s %-20s %s\n",NR, FNR,$4,$5,$6}' netstat.txt
指定分隔符:
- awk 'BEGIN{FS=":"} {print $1,$3,$6}' /etc/passwd
或者awk -F:
- '{print $1,$3,$6}' /etc/passwd
以\t作为分隔符输出:
- awk -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd
1.3 字符串匹配:
~表示匹配模式开始,正则表达式匹配。
- awk '$6 ~ /TIME/ || NR ==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
- awk '$6 ~ /ESTABLISHED/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
- awk '/LISTEN/' netstat.txt
使用“/TIME|ESTABLISHED/” 来匹配TIME 或者ESTABLISHED :
- awk '$6 ~ /FIN|TIME/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
模式取反:!~
- awk '$6 !~ /TIME/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
或者awk '!/WAIT/' netstat.txt
1.4 拆分文件:
使用数据流重定向”>”
- awk 'NR!=1 {print > $6}' netstat.txt NR!=1表示不处理表头
把指定的列输出到文件:
- awk 'NR!=1{print $4,$5 > $6}' netstat.txt
使用程序流进行条件拆分:if else
- awk 'NR!=1{if($6 ~ /TIME|ESTABLISHED/) print > "1.txt";
- else if($6 ~ /LISTEN/) print > "2.txt";
- else print > "3.txt"}' netstat.txt
1.5 统计
计算所有的C文件,CPP文件和H文件的文件大小总和:
- ls -l *.cpp *.c*.h | awk '{sum+=$5} END {print sum}'
统计各个connection状态的用法:使用数组
- awk 'NR!=1{a[$6]++;} END {for (i in a) print i ", " a;}' netstat.txt
统计每个用户的进程的占了多少内存:
- ps aux| awk 'NR!=1{a[$1]+=$6;} END { for(i in a) print i ", " a"KB";}'
数组:因为awk中数组的下标可以是数字和字母,数组的下标通常被称为关键字(key)。值和关键字都存储在内部的一张针对key/value应用hash的表格里。由于hash不是顺序存储,因此在显示数组内容时会发现,它们并不是按照你预料的顺序显示出来的。数组和变量一样,都是在使用时自动创建的,awk也同样会自动判断其存储的是数字还是字符串。一般而言,awk中的数组用来从记录中收集信息,可以用于计算总和、统计单词以及跟踪模板被匹配的次数等等。
1.6 使用脚本进行文本、数据处理
BEGIN、END关键字:BEGIN表示处理所有行之前的标识,END表示处理完所有行后的标识,具体语法:
BEGIN { 这里面放的是执行前的语句}
END {这里面放的是处理完所有的行后要执行的语句}
{这里面放的是处理每一行时要执行的语句}
实例操作文件:cat cal.awk
- #!/bin/awk -f
- #运行前
- BEGIN {
- math= 0
- english= 0
- computer= 0
- printf"NAME NO. MATH ENGLISH COMPUTER TOTAL\n"
- printf"---------------------------------------------\n"
- }
- #运行中
- {
- math+=$3
- english+=$4
- computer+=$5
- printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
- }
- #运行后
- END{
- printf"---------------------------------------------\n"
- printf "TOTAL:%10d %8d %8d \n", math, english, computer
- printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR,computer/NR
- }
执行:awk -f cal.awk score.txt
1.7 变量声明和环境变量:
使用-v参数进行变量声明,ENVIRON关键字表示环境变量
- $ x=5
- $ y=10
- $ export y #y被export为环境变量
- $ echo $x $y
- 5 10
- $awk -v val=$x '{print $1, $2, $3, $4+val, $5+ENVIRON["y"]}' OFS="\t" score.txt
2. sed:流编辑器
stream editor,流编辑器,用程序的方式来编辑文本,正则表达式进行模式匹配。sed本身是一个管道命令,可以分析standard input,也可以将数据进行替换、删除、新增、撷取特定行等功能。
演示文本:catpets.txt
- This is my cat
- my cat's name is betty
- This is my dog
- my dog's name is frank
- This is my fish
- my fish's name is george
- This is my goat
- my goat's name is adam
使用:sed [-nefr] action
action:-i直接修改读取的档案内容,而不是由屏幕输出,-r表示支持延伸型正则表达式的语法。
动作说明:[n1[,n2]] function n1,n2表示要选择的行数,function包括:
a-新增,c-取代,d-删除,i-插入,p-打印,s-取代(可以直接进行取代的工作,例如 1,20s/old/new/g)
2.1 用s命令进行替换
my字符串替换成Rango Chen’s
- sed “s/my/Rango Chen's/g” pets.txt
ps:如果使用单引号,则无法通过\'来转义。该命令并没有对文件内容进行更改,只是把处理过后的内容输出,如果你要写回文件,你可以使用重定向:
- sed "s/my/Rango Chen's/g" pets.txt >Chen_pets.txt
,或者使用-i选项:
- sed -i “s/my/Rango Chen's/g” pets.txt
s表示替换动作,/g表示一行上的替换所有的匹配。
在每一行最前面加上#:
- sed 's/^/#/g' pets.txt
在每一行的末尾加上---:
- sed 's/$/ --- /g' pets.txt
基础的正则表示法特殊字符:
- ^ 表示一行的开头。如:/^#/ 以#开头的匹配。
- $ 表示一行的结尾。如:/}$/ 以}结尾的匹配。
- \< 表示词首。如\<abc 表示以abc 为首的詞。
- \> 表示词尾。如 abc\> 表示以abc 結尾的詞。
- \ 将特殊字符进行转义,还原其本身意义:grep -n \' pets.txt 搜寻含有单引号'的那一行。
- . 表示任何单个字符。
- * 表示某个字符出现了0次或多次。
- [ ] 字符集合。如:[abc]表示匹配a或b或c,还有[a-zA-Z]表示匹配所有的26个字符。如果其中有^表示取反,如[^a]表示非a的字符
- \{n,m\} 连续n到m个的“前一个RE字符” grep -n 'go\{2,3\}g' 1.txt 在g与g之间有2到3个o存在的字符串,亦即(goog)(gooog)
去掉某html中的tags:
html.txt:
- <b>This</b>is what <span style="text-decoration:underline;">I</span> meant. Understand?
- sed 's/<[^>]*>//g' html.txt
只替换第3到第6行的文本:
- sed "3,6s/my/your/g" pets.txt
只替换第3行的文本:
- sed "3s/my/your/g" pets.txt
只替换每一行的第一个s:
- sed 's/s/S/1' my.txt 1表示第一个
只替换每一行的第二个s:
- sed 's/s/S/2' my.txt 2表示第二个
只替换第一行的第3个以后的s:
- sed 's/s/S/3g' my.txt
2.2 多个匹配
一次替换多个模式,每个模式之间用;进行间隔:
- sed '1,3s/my/your/g; 3,$s/This/That/g' my.txt
上面的命令等价于:
- sed -e'1,3s/my/your/g' -e '3,$s/This/That/g' my.txt
使用&来当做被匹配的变量,加入一些字符:
- sed 's/my/[&]/g' my.txt
此命令相当于在my两边加上[]
2.3 圆括号匹配
圆括号括起来的正则表达式所匹配的字符串会可以当成变量来使用,sed中使用的是\1,\2…
- sed 's/This is my \([^,]*\),.*is \(.*\)/\1:\2/g' my.txt
- cat:betty
- dog:frank
- fish:george
- goat:adam
2.4 基本知识点
1)Pattern Space:关于参数-n,表示取消默认输出,相当于--quiet,--silent。在sed处理文件的时候,每一行都被保存在一个叫模式空间的临时缓冲区中,除非行被删除或者输出被取消,否则所有被处理的行都将打印在屏幕上。接着模式空间被清空,并存入新的一行等待处理。
2)Address:[address[,address]][!]{cmd},其中的!表示匹配成功后是否执行命令,address可以是一个数字,也可以是一个模式,可以通过逗号分隔两个address表示两个address的区间。
3)命令打包:cmd可以是多个,它们可以用分号分开,可以用大括号括起来作为嵌套命令
对3行到第6行,匹配/This/成功后,再匹配/fish/,成功后执行d命令:
- sed '3,6 {/This/{/fish/d}}' pets.txt
从第一行到最后一行,如果匹配到This,则删除之;如果前面有空格,则去除空格:
- sed '1,${/This/d ; s/^ *//g}' pets.txt
4)HoldSpace:保持空间
- g:将hold space中的内容拷贝到pattern space中,原来pattern space里的内容清除
- G:将hold space中的内容append到pattern space\n后
- h:将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除
- H:将pattern space中的内容append到hold space\n后
- x:交换pattern space和hold space的内容
sed -e '/test/h' -e '$G‘ example:在这个例子里,匹配test的行被找到后,将存入模式空间,h命令将其复制并存入一个称为保持缓存区的特殊缓冲区内。第二条语句的意思是,当到达最后一行后,G命令取出保持缓冲区的行,然后把它放回模式空间中,且追加到现在已经存在于模式空间中的行的末尾。在这个例子中就是追加到最后一行。简单来说,任何包含test的行都被复制并追加到该文件的末尾。
sed -e '/test/h' -e '/check/x' example:互换模式空间和保持缓冲区的内容。也就是把包含test与check的行互换。
5)执行sed脚本:sed -f test.sed
Sed对于脚本中输入的命令非常挑剔,在命令的末尾不能有任何空白或文本,如果在一行中有多个命令,要用分号分隔。以#开头的行为注释行,且不能跨行。
ps: 去除空白行:sed '/^ *$/d' file
3. sort:文本内容排序
语法:
- sort [-bcdfimMnr] [-o<输出文件>] [-t<分隔字符>] [+<起始栏位>-<结束栏位>] [--help] [--verison] [文件]
参数:
- -b 忽略每行前面开始出的空格字符。
- -c 检查文件是否已经按照顺序排序。
- -d 排序时,处理英文字母、数字及空格字符外,忽略其他的字符。
- -f 排序时,将小写字母视为大写字母。
- -i 排序时,除了040至176之间的ASCII字符外,忽略其他的字符。
- -m 将几个排序好的文件进行合并。
- -M 将前面3个字母依照月份的缩写进行排序。
- -n 依照数值的大小排序。
- -o<输出文件> 将排序后的结果存入指定的文件。
- -r 以相反的顺序来排序。
- -t<分隔字符> 指定排序时所用的栏位分隔字符。
- +<起始栏位>-<结束栏位> 以指定的栏位来排序,范围由起始栏位到结束栏位的前一栏位。
- --help 显示帮助。
- --version 显示版本信息
4. uniq:
显示唯一的行,对于那些连续重复的行只显示一次,以及计数重复的行
uniq:不加任何参数表示匹配第一次出现的那行
uniq -c:显示重复的行的行数
uniq -u:仅显示文件中没有连续出现的行,唯一行
uniq -d:仅显示文件中连续重复出现的行。
5. cut:
片段撷取工具,可以从一个文本文件或者文本流中提取文本列
5.1 命令用法
- cut -b list [-n] [file ...]
- cut -c list [file ...]
- cut -f list [-d delim][-s][file ...]
-b、-c、-f分别表示字节、字符、字段(即byte、character、field);list表示-b,-c,-f操作范围,-n表示具体数字,with -b: don’t split multibyte characters;file表示的自然是要操作的文本文件的名称;delim(英文全写:delimiter)表示分隔符,默认情况下为TAB;-s表示不包括那些不含分隔符的行(这样有利于去掉注释和标题)。
--output-delimiter=字符串,使用指定的字符串作为输出分界符,默认采用输入的分界符。上面三种方式中,表示从指定的范围中提取字节(-b)、或字符(-c)、或字段(-f)。
LIST的范围:
- N 只有第N项
- N- 从第N项一直到行尾
- N-M 从第N项到第M项(包括M)
- -M 从一行的开始到第M项(包括M)
- - 从一行的开始到结束的所有项
5.2 用法实例
撷取/etc/passwd文件中的前十五个用户名:
- cut -f1 -d: /etc/passwd | head -15
撷取/etc/passwd文件每一行前十个字节的内容:
- cut -b 1-10 /etc/passwd
撷取该文件每一行第1,4,7个字节的内容:
- cut -b 1,4,7 /etc/passwd
将/etc/passwd的分隔符换成“|”输出:
- cut -d: -f 1- -s --output-delimiter=”|” /etc/passwd
6. grep:
撷取具有特定信息的行,逐行操作。
用法:grep [-acinv] [--color=auto] '搜寻字符串' filename
- -a : 将binary档案以text 档案的方式搜寻数据
- -c: 计算找到'搜寻字符串'的次数
- -i: 忽略大小写的不同,所以大小写视为相同
- -n : 顺便输出行号
- -v : 反向选择,亦即显示出没有'搜寻字符串'内容的那一行!
- --color=auto: 可以将找到的关键词部分加上颜色的显示!
7. wc:
统计单词。
用法:wc [-lwmc]
- -l : 仅列出行;
- -w : 仅列出多少字(英文单字);
- -m : 多少字符;
- -c: 多少字节
不加任何参数表示全部列出。
实例:/etc/man.config 里面有多少相关字、行、字符数:
- cat /etc/man.config | wc
原文发布时间为:2014-04-17
本文来自云栖社区合作伙伴“Linux中国”