对于一些文件字段或文件名等截取或重命名等操作,我们一般会用到正则等方法实现,Linux中的grepawksed命令同样能得到上述的效果,本文主要是介绍这三者的区别和用法。

本文参考文章:linux命令小记(grep、awk、sed)

grep命令

grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。

常用选项

补充:egrep命令用于在文件内查找指定的字符串,egrep执行效果与grep -E相似。fgrep命令grep -F命令是一样的,但出错和用法消息不同,-s 标志功能也不同。

常见用法

在文件中搜索一个单词,命令会返回一个包含“match_pattern”的文本行:

grep match_pattern file_name
grep "match_pattern" file_name

# 多文件查找
grep "match_pattern" file_1 file_2 file_3 ...

# 标记匹配颜色
grep "match_pattern" file_name --color=auto

使用正则匹配:

grep -E "[1-9]+"
egrep "[1-9]+"

# 只输出文件中匹配到的部分
echo this is a test line. | grep -o -E "[a-z]+\."
echo this is a test line. | egrep -o "[a-z]+\."
> line.

# 忽略大小写
echo "hello world" | grep -i "HELLO"
>hello

多个匹配样式:

echo this is a text line | grep -e "is" -e "line" -o
>is
>line

# 也可以使用-f选项来匹配多个样式,在样式文件中逐行写出需要匹配的字符。
cat patfile
>aaa
>bbb

echo aaa bbb ccc ddd eee | grep -f patfile -o
>aaa
>bbb

在多级目录中对文本进行递归搜索:

# .表示当前目录
grep "text" . -r -n

#只在目录中所有的.php和.html文件中递归搜索字符"main()"
grep "main()" . -r --include *.{php,html}

#在搜索结果中排除所有README文件
grep "main()" . -r --exclude "README"

#在搜索结果中排除filelist文件列表里的文件
grep "main()" . -r --exclude-from filelist

awk命令

awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。

常用命令和选项

awk [options] 'script' var=value file(s)
awk [options] -f scriptfile var=value file(s)

选项

awk内置变量(预定义变量)

$n 当前记录的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段。 
$0 这个变量包含执行过程中当前行的文本内容。
ARGC 命令行参数的数目。
ARGV 包含命令行参数的数组。
FILENAME 当前输入文件的名。
FS 字段分隔符(默认是任何空格)。
NF 表示字段数,在执行过程中对应于当前的字段数。
NR 表示记录数,在执行过程中对应于当前的行号。
OFMT 数字的输出格式(默认值是%.6g)。
OFS 输出字段分隔符(默认值是一个空格)。
ORS 输出记录分隔符(默认值是一个换行符)。
RS 记录分隔符(默认是一个换行符)。

简单用法

打印每一行的第二、第三和最后一个字段:

awk '{ print $2,$3,$NF }' filename

打印第一行:

awk 'NR==1{print}' filename

统计文件中的行数:

awk 'END{ print NR }' filename

指定分隔符:

echo 111__222__333 | awk 'BEGIN{FS="__"}{print $1}'
echo 111__222__333 | awk -F "__" '{print $1}'
>111

匹配:

# 输出正则匹配"match_pattern"的一行
awk '/match_pattern/' filename

# 输出正则匹配第二个字段的行
awk '{if($2~/^80$/)print}' filename

# 输出正则不匹配第二个字段的行
awk '{if($2!~/^80$/)print}' filename

# 输出第二个字段为"match_pattern"的行
awk '{if($2=="match_pattern")print}' filename

sed命令

sed操作的是一个输入文件在内存的一个副本,对副本内容进行编辑活动,如果没有重定向到一个文件,会将文件修改的结果输出到屏幕。和awk一样,不会修改输入文件的内容。

基本命令和选项

sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)

选项

命令

替换标记

元字符集

常用用法

替换文本中的字符串:

sed 's/book/books/' file

# -n选项和p命令一起使用表示只打印那些发生替换的行
sed -n 's/test/TEST/p' file

# 直接编辑文件选项-i,会匹配file文件中每一行的第一个book替换为books
sed -i 's/book/books/g' file

# 当需要从第N处匹配开始替换时,可以使用 /Ng
echo sksksksksksk | sed 's/sk/SK/3g'
>skskSKSKSKSK

删除操作:

# 删除空白行
sed '/^$/d' file

# 删除文件的第2行
sed '2d' file

# 删除文件的第2行到末尾所有行
sed '2,$d' file

最后

如果只是过滤文本,可使用grep,其效率要比其他的高很多。sed默认只处理模式空间,不处理原数据,如果你处理的数据是针对行处理的,可以使用sed。如果对处理的数据需要生成报告之类的信息,或者你处理的数据是按列进行处理的,最好使用awk。

本文由 小TiD笔记 发布在小TiD笔记,转载此文请保持文章完整性,并请附上文章来源(小TiD笔记)及本页链接。

原文链接: https://www.tidnotes.ga/2020/02/linux-grep-awk-sed.html