对于一些文件字段或文件名等截取或重命名等操作,我们一般会用到正则等方法实现,Linux中的 grep、awk、sed 命令同样能得到上述的效果,本文主要是介绍这三者的区别和用法。
本文参考文章:linux命令小记(grep、awk、sed)
grep命令
grep
(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。
常用选项
-c
计算匹配的列数。-C<显示列数>或-<显示列数>
除了显示匹配的那一列之外,并显示该列之前后的内容。-d<进行动作>
当指定要查找的是目录而非文件时,必须使用这项参数,否则grep命令将回报信息并停止动作。-e<范本样式>
指定字符串作为查找文件内容的范本样式。-E
将范本样式为延伸的普通表示法来使用,意味着使用能使用扩展正则表达式。-f<范本文件>
指定范本文件,其内容有一个或多个范本样式,让grep查找符合范本条件的文件内容,格式为每一列的范本样式。-F
将范本样式视为固定字符串的列表。-h
在显示匹配的那一列之前,不标示该列所属的文件名称。-H
在显示匹配的那一列之前,标示该列的文件名称。-i
忽略字符大小写的差别。-l
列出文件内容匹配的文件名称。-L
列出文件内容不匹配的文件名称。-n
在显示匹配的那一列之前,标示出该列的编号。-q
不显示任何信息。-R/-r
此参数的效果和指定-d recurse
参数相同。-s
不显示错误信息。-v
反转查找。-y
此参数效果跟-i
相同。-o
只输出文件中匹配到的部分。
补充:
egrep
命令用于在文件内查找指定的字符串,egrep执行效果与grep -E
相似。fgrep
命令和grep -F
命令是一样的,但出错和用法消息不同,-s
标志功能也不同。
常见用法
在文件中搜索一个单词,命令会返回一个包含 "match_pattern"
的文本行:
1 | grep match_pattern file_name |
使用正则匹配:
1 | grep -E "[1-9]+" |
多个匹配样式:
1 | echo this is a text line | grep -e "is" -e "line" -o |
在多级目录中对文本进行递归搜索:
1 | # .表示当前目录 |
awk命令
awk
是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入( stdin
)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。
常用命令和选项
1 | awk [options] 'script' var=value file(s) |
选项
-F fs
fs指定输入分隔符,fs可以是字符串或正则表达式,如-F :
。-v var=value
赋值一个用户定义变量,将外部变量传递给awk
。-f scripfile
从脚本文件中读取awk
命令。-m[fr] val
对val
值设置内在限制,-mf
选项限制分配给val的最大块数目;-mr
选项限制记录的最大数目。这两个功能是Bell实验室版awk
的扩展功能,在标准awk
中不适用。
awk内置变量(预定义变量)
1 | $n 当前记录的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段。 |
简单用法
打印每一行的第二、第三和最后一个字段:
1 | awk '{ print $2,$3,$NF }' filename |
打印第一行:
1 | awk 'NR==1{print}' filename |
统计文件中的行数:
1 | awk 'END{ print NR }' filename |
指定分隔符:
1 | echo 111__222__333 | awk 'BEGIN{FS="__"}{print $1}' |
匹配:
1 | # 输出正则匹配"match_pattern"的一行 |
sed命令
sed
操作的是一个输入文件在内存的一个副本,对副本内容进行编辑活动,如果没有重定向到一个文件,会将文件修改的结果输出到屏幕。和 awk
一样,不会修改输入文件的内容。
基本命令和选项
1 | sed [options] 'command' file(s) |
选项
-e <script>或--expression=<script>
以选项中的指定的script来处理输入的文本文件;-f <script文件>或--file=<script文件>
以选项中指定的script文件来处理输入的文本文件;-h或--help
显示帮助;-n或--quiet或--silent
仅显示script处理后的结果;-V或--version
显示版本信息。
命令
a\
在当前行下面插入文本。i\
在当前行上面插入文本。c\
把选定的行改为新的文本。d
删除,删除选择的行。s
替换指定字符。p
打印模板块的行。r file
从file中读行。w file
写并追加模板块到file末尾。!
表示后面的命令对所有没有被选定的行发生作用。=
打印当前行号码。
替换标记
g
表示行内全面替换。p
表示打印行。w
表示把行写入一个文件。x
表示互换模板块中的文本和缓冲区中的文本。y
表示把一个字符翻译为另外的字符(但是不用于正则表达式)。\n
第n个匹配字符串。&
已匹配所有字符串。
元字符集
^
匹配行开始,如:/^sed/
匹配所有以sed开头的行。$
匹配行结束,如:/sed$/
匹配所有以sed结尾的行。.
匹配一个非换行符的任意字符,如:/s.d/
匹配s后接一个任意字符,最后是d。*
匹配0个或多个字符,如:/*sed/
匹配所有模板是一个或多个空格后紧跟sed的行。[]
匹配一个指定范围内的字符,如:/[sS]ed/
匹配sed和Sed。[^]
匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/
匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。\(..\)
匹配子串,保存匹配的字符,如:s/\(love\)able/\1rs/
,loveable被替换成lovers。&
保存搜索字符用来替换其他字符,如:s/love/**&**/
,love这成**love**。\<
匹配单词的开始,如:/\<love/
匹配包含以love开头的单词的行。\>
匹配单词的结束,如:/love\>/
匹配包含以love结尾的单词的行。x\{m\}
重复字符x,m次,如:/0\{5\}/
匹配包含5个0的行。x\{m,\}
重复字符x,至少m次,如:/0\{5,\}/
匹配至少有5个0的行。x\{m,n\}
重复字符x,至少m次,不多于n次,如:/0\{5,10\}/
匹配5~10个0的行。
常用用法
替换文本中的字符串:
1 | sed 's/book/books/' file |
删除操作:
1 | # 删除空白行 |
最后
如果只是过滤文本,可使用 grep
,其效率要比其他的高很多。sed
默认只处理模式空间,不处理原数据,如果你处理的数据是针对行处理的,可以使用 sed
。如果对处理的数据需要生成报告之类的信息,或者你处理的数据是按列进行处理的,最好使用 awk
。