shell grep、awk、sed
时间:2023-06-10 19:07:00
文章目录
-
-
-
- grep
- sed
- awk
-
-
参考菜鸟教程:https://www.runoob.com/linux/
grep
grep
命令用于查找文件里符合条件的字符串。
参数:
-a 或 --text
: 不要忽视二进制数据。-A<显示行数> 或 --after-context=<显示行数>
: 除了显示符合模型风格的列外,还显示行后的内容。-b 或 --byte-offset
: 在显示符合样式的行之前,标注行的第一个字符号。-B<显示行数> 或 --before-context=<显示行数>
: 除了显示符合风格的行,并显示行之前的内容。-c 或 --count
: 计算符合样式的列数。-C<显示行数> 或 --context=<显示行数>或-<显示行数>
: 除了显示符合风格的行外,还显示行前后的内容。-d <动作> 或 --directories=<动作>
: 当指定要找到的是目录而不是文件时,必须使用该参数,否则grep
指令将返回信息并停止行动。-e<范本样式> 或 --regexp=<范本样式>
: 指定字符串作为搜索文件内容的样式。-E 或 --extended-regexp
: 使用延伸样式的正则表达式。-f<规则文件> 或 --file=<规则文件>
: 指定的规则文件包含一个或多个规则样式grep
以每行规则样式查找符合规则条件的文件内容。-F 或 --fixed-regexp
: 列表将样式视为固定字符串。-G 或 --basic-regexp
: 使用风格作为一种普通的表达方式。-h 或 --no-filename
: 在显示符合样式的行之前,不要标明该行的文件名称。-H 或 --with-filename
: 在显示符合样式的行之前,表示该行的文件名称。-i 或 --ignore-case
: 忽略字符大小写的差异。-l 或 --file-with-matches
: 列出符合规定风格的文件名称。-L 或 --files-without-match
: 列出不符合指定风格的文件名称。-n 或 --line-number
: 在显示符合样式的行之前,标注该行的列号。-o 或 --only-matching
: 只显示匹配PATTERN 部分。-q 或 --quiet或--silent
: 不显示任何信息。-r 或 --recursive
: 此参数的效果和指定"-d recurse"参数相同。-s 或 --no-messages
: 不要显示错误的信息。-v 或 --invert-match
: 显示不包括所有匹配文本的行。-V 或 --version
: 显示版本信息。-w 或 --word-regexp
: 只显示符合全字符的列。-x --line-regexp
: 只显示符合全列的列。-y
: 本参数的效果及指定"-i"参数相同。
常用指令:
# 递归搜索并显示行号;自动添加文件名称,可添加-h取消 grep -rn "test" ./* # 查找不包含test并显示行号、文件名称 grep -Hvn "test" test.file # 忽略大小写, 全字匹配,行号显示 grep -iwn "test" test.file # 除了显示匹配行外,还显示每个匹配行的前2行和后1行,并显示行号 grep -n -A1 -B2 "test" test.file # 使用正则 grep -e "^test$" test.file # 统计匹配行数;自动添加文件名称 grep -cr "test" ./*
sed
Linux
sed
命令是用脚本处理文本文件。
sed
文本文件可以根据脚本的指令进行处理和编辑。
sed
主要用于自动编辑一个或多个文件,简化文件的重复操作,编写转换程序等。
参数:
-e
或--expression=
在选项中指定script
处理输入的文本文件。-f
或--file=
在选项中指定script
处理输入的文本文件。-h
或--help
显示帮助。-n
或--quiet
或--silent
仅显示script
自动打印模式空间被取消。-V
或--version
显示版本信息。-c
或--copy
,在-i
模式中shuffling files使用副本而不是重命名
动作说明:
增删改查:
a
:新增,a
字串可以在后面连接,这些字串可以添加到当前下一行c
:取代,c
字串可以在后面连接,可以替代code>n1,n2
之间的行d
:删除,后面不需加任何东西i
:插入,i
的后面可以接字串,这些字串添加在当前行的上一行p
:打印,将选中行打印出来。通常p
会与参数-n
一起运行,来保证只打印选中行s
:取代,取代指定行的指定字符,如1,2s/old/new/g
模式空间
(pattern space)
、缓存空间(hold space)
:
处理数据流程:将处理的行读入模式空间,然后根据sed
命令处理,最后清空模式空间,这里存在缓存空间的概念,即在处理所有行时缓存空间的数据一直存在,除非被覆盖
h
:将当前模式空间中内容覆盖到缓存区H
:将当前模式空间中的内容追加到缓存区g
:将当前缓存区中的内容覆盖到模式空间G
:将当前缓存区中的内容追加到模式空间x
:将当前缓存区和模式空间内容互换其他有关模式空间的动作:
n
:提前读取下一行,并覆盖当前模式空间的内容N
:提前读取下一行,并追加到当前模式空间,即将两行看作一行处理,但中间存在换行符p
:打印当前模式空间的所有内容,追加到默认输出中P
:打印当前模式空间开端至\n
的内容,追加到默认输出中d
:删除模式空间的内容并导致读入新的输入行,并且在脚本顶端重新使用编辑方法D
:删除当前模式空间开端至\n的内容,不会导致读入新的输入行并且它返回到脚本的顶端y
:对之前匹配的字符逐个替换
常用指令:
以下指令未实际修改文件(添加参数-i直接修改文件,建议先备份)
:
# 在指令行前、行后插入一行或多行内容,多行需手动添加\n
# 在1-3行后增加一行test;
#1,$a: 1-最后一行;
#1a:第一行
sed '1,3a test' test.file
# 在1-3行前增加一行test;
sed '1,3i test' test.file
# 删除指定行
# 删除第一行
sed '1d' test.file
# 删除1-3行;1,$:1-最后一行
sed '1,3d' test.file
# 替换指定行的内容
# 将1-3行的内容替换为指令内容;1c:第一行;1,$c:1-最后一行
sed '1,3c hello world' test.file
# 打印指定行内容
# 打印1-3行内容;1p:第一行;1-$:1-最后一行;-n:输出处理结果,不显示所有行
sed -n '1,3p' test.file
# 数据搜寻并打印
# 打印文件中所有包含test字符的行;-n:输出处理结果,不显示所有行
sed -n '/test/p' test.file
# 数据搜寻并删除
# 删除文件中所有包含test字符的行
sed '/test/d' test.file
# 数据搜寻并指令命令
# 查找包含test的行,并将这些行中的hello字符替换成hi,然后打印出来
sed -n '/test/{s/hello/hi/;p}' test.file
# 数据搜寻并替换,非替换整行,而是以行为单位进行数据的搜寻并替换
# 将所以行中的hello替换成hi
sed 's/hello/hi/g' test.file
# 删除所以行中的hello
sed 's/hello//g' test.file
# 多次编辑
# 先删除第一行,然后删除所有行中的hello,最后打印修改结果
sed -n -e '1d' -e 's/hello//g' -e 'p' test.file
# 也可以使用sed脚本文件
# 文件内容,cat test.sed:
1d
s/hello//g
p
# 使用:
sed -n -f test.sed test.file # 取消自动打印模式空间
#在所有行前增加head 字符
sed 's/^/head /g' test.file
#在所有行后增加 end字符
sed 's/$/ end/g' test.file
模式空间相关命令
# 读取第一行数据并执行''中的脚本进行处理,n读取下一行并覆盖得出2,p打印2,处理完一行;继续读取下一行继续同样处理 ... 最后即为输出所有偶数行
sed -n 'n;p' test.file
# 读取第一行数据并执行''中的脚本进行处理,n读取下一行并追加得出1\n2,P打印1\n,处理完一行,清空模式空间;继续读取下一行继续同样处理 ... 最后即为输出所有奇数行
# $!: 不是尾行为真, 即不是尾行则执行N, 是尾行则不执行N, 这里防止是奇数行时执行N去读取下一行读取失败后跳出脚本不执行P, 即不打印最后一行
sed -n '$!N;P' test.file
# 读取第一行数据并执行''中的脚本进行处理,n读取下一行并覆盖得出2,d删除2读取下一行得出3并跳转到脚本顶端,n读取下一行并覆盖得出4 ...,最后n或d读取不到下一行时结束处理,输出结果即为未删除的行,即删除了所有偶数行
sed 'n;d' test.file
# 读取第一行数据并执行''中的脚本进行处理,N读取下一行并追加的出1\n2,D删除1\n剩余2且不读取输入跳转到脚本顶端,N读取下一行得出2\n3,D删除2\n得3,... 最后N读取不到下一行,输出结果即得出最后一行数据,其他数据都被删了
sed 'N;D' test.file
# 读取第一行数据并执行''中的脚本进行处理,H将当前行追加到缓存空间(\n1\n),g将缓存区内容覆盖到模式空间,此时得出\n1,清楚缓存空间继续下一次读取,...
# h、G类似
sed 'H;g' test.file
# 读取第一行数据并执行''中的脚本进行处理,将行中所有a都替换成A
sed 'y/a/A/' test.file
# 将含有test的行覆盖到缓存空间,然后在含有hello的行内容与缓存空间的内容互换,
sed -e '/test/h' -e '/hello/x' test.file
awk
awk
是一种处理文本文件的语言,是一个强大的文本分析工具。
awk工作原理:
流程可分为三个部分:
- 执行
BEGIN
块的内容- 读取每一条记录并执行
BODY
块。- 执行
END
块模块内容,END
块可以输出最终结果。
参数:
-F fs
或--field-separator fs
:指定输入字段分隔符,fs
是一个字符串或者是一个正则表达式,如-F:。-v var=value
或--asign var=value
赋值一个用户定义变量。-f scripfile
或--file scriptfile
从脚本文件中读取awk
命令。
内建变量:
常用:
FS
:输入字段分隔符(Field Separator)
,默认为空格字符OFS
:输出字段分隔符(Output Field Separator)
,默认为空格字符RS
:记录分隔符(Record Separator)
,读取文件时,默认将一行作为一条记录,及默认分隔符为换行符ORS
:输出记录分隔符(Output Record Separator)
,每条记录在输出时候会用分隔符隔开,默认分隔符为换行符NR
:记录数(Number of Record)
表示的是已经处理过的总记录数目,或者说行号(不一定是一个文件,可能是多个)NF
:一条记录的字段数目(Number for Field)
FILENAME
:当前输入文件的名字FNR
:当前输入文件的记录数目,当awk
读取多个文件时,NR
代表的是当前输入所有文件的全部记录数,而FNR
则是当前文件的记录数。$n
:当前记录的第n个字段,字段间由FS
分隔,n为自然数$0
:完整的输入记录IGNORECASE
:如果为真,则进行忽略大小写的匹配ARGC
:命令行参数的数目
常用指令:
awk [option] 'BEGIN{ commands } pattern{ commands } END{ commands }' <filename># 行匹配语句 awk '' 只能用单引号
# 过滤第一列大于2并且第二列等于'test'的行
awk '$1>2 && $2=="test" {print $0}' test.file
# 指定RS、ORS、FS、OFS,每一行输出FILENAME、$1、NF、NR、FNR
awk 'BEGIN{RS="\n";ORS="\n";FS=" ";OFS=" "}{print FILENAME,$1,NF,NR,FNR}' test.file
# 使用正则,字符串匹配
# 输出第一列包含"test"的行,忽略大小写,并打印第一列和第二列;!~:不包含
awk 'BEGIN{IGNORECASE=1} $1 ~ /test/ {print $1,$2}' test.file
脚本编写
-
awk
脚本文件test.awk
脚本文件内容:#运行前要执行的语句 BEGIN { printf "-----------------------start-----------------------\n" } #运行中,处理每一条记录时要执行的语句 { printf "process each record\n" } #运行后要执行的语句 END { printf "------------------------end------------------------\n" }
运行:
awk -f test.awk test.file
-
数组:
#array_name:数组的名称;index:数组索引;value:数组中元素所赋予的值 array_name[index]=value # 创建数组 array_name[index]=value # 删除数组元素 delete array_name[index] # awk不支持
多维数组,可用不同key实现,如array_name["0,1"]=value # 遍历 awk 'BEGIN{ array_name[2]="1"; for (i in array_name) { print "key: ", i, ", value: ", array_name[i] } }'
- 条件语句
格式
if (condition-1)
action-1
else if (condition-2)
action-2
else
action-3
# eg:
awk 'BEGIN{num=10;if(num%2==0)printf "%d 是偶数\n", num;else printf "%d 是奇数\n", num}'
- 循环
for (initialisation; condition; increment/decrement) {
action-1;
action-2
}
# eg:
awk 'BEGIN{for(i=0;i!=2;){printf("i: %d\n",i);i++}}'
while (condition) {
action-1;
action-2;
}
continue;
break;
exit(10); # 10为返回状态,可通过echo $?获取
-
函数
内置函数参考:https://www.runoob.com/w3cnote/awk-built-in-functions.html
awk
脚本内容:
func min(num1, num2)
{
if (num1 < num2)
return num1
return num2
}
func main()
{
num1 = 1
num2 = 2
result = min(num1, num2)
printf("min num: %d", result)
}
BEGIN{
main()
}
- 运算符
运算符 | 描述 |
---|---|
= += -= *= /= %= ^= **= | 赋值 |
?: | C条件表达式 |
|| | 逻辑或 |
&& | 逻辑与 |
~ 和 !~ | 匹配正则表达式和不匹配正则表达式 |
< <= > >= != == | 关系运算符 |
空格 | 连接 |
+ - | 加,减 |
* / % | 乘,除与求余 |
+ - ! | 一元加,减和逻辑非 |
^ | 求幂 |
++ – | 增加或减少,作为前缀或后缀 |
$ | 字段引用 |
in | 数组成员 |