grep、sed、awk

正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。

正则表达式由一些普通字符和一些元字符(metacharacters)组成。


检索工具:grep

grep [-cinvABC] 'word' filename:根据关键字或正则表达式在文件中查找匹配的行

  • -c:显示匹配行数

  • -i:不区分大小写

  • -n:显示行号

  • -v:显示不匹配的行

  • -An:连匹配行的下面n行一起显示

  • -Bn:连匹配行的上面n行一起显示

  • -Cn:连匹配行的上下n行一起显示

  • --color:将匹配到的关键字用红色标识

  • -r:递归查询某个目录下的所有文件

    • --include=FILE_PATTERN:只搜索匹配表达式的文件

    • --exclude=FILE_PATTERN:不搜索匹配表达式的文件

    • --exclude-dir=PATTERN:不搜索匹配表达式的目录

正则表达式之元字符

  • '[0-9]' 表示包含任意数字

  • '[a-zA-Z]' 表示包含任意字母

  • '^word' 表示首字符是word

  • 'word$' 表示尾字符是word

  • '^$' 表示空行;在正则表达式中^被定义为行首,$被定义为行尾

  • '^[a-zA-Z]' 表示以字母开头的行

  • '^[^0-9]' 表示以非数字字符开头的行;说明:在[]里面加^表示取非

  • . 表示一个任意字符

  • .*表示任意个任意字符,包括空行

    • 以下几个是用来处理重复字符的元字符

  • * 表示任意个*前面的字符,等价\{0,\};如'r*t'匹配了't'、'rt'、'rrt'…

  • + 匹配1个或1个以上的+前面的字符,等价\{1,\};如'r+t'匹配了'rt'、'rrt'…不匹配'rt'

  • ?匹配0个或1个?前面的字符,等价\{0,1\};如'r\?t'匹配了't'、'rt'

  • c{n} 匹配n个c(字符)

  • c{n,} 匹配n个或n个以上的c

  • c{n,m}匹配字符c的个数范围表示最少匹配n个c,最多匹配m个c

    • =====================================

  • 'word_1|word_2' 管道符表示,匹配word_1或word_2

  • '(root)?' 小括号表示一个整体,是一个字,主要用来和处理重复字符的元字符结合使用

标蓝底的是属于egrep的扩展元字符如果要在grep中使用egrep的扩展元字符,必须使用-E参数或加\;

如\+、\?、\{n\}、\{n,\}、\{n,m\}、\|、\(word\)


注:可以使用管道符实现多层过滤,如下:只查看文件中可执行的语句。

[root@localhost ~]# grep -v '^#' ~/.bash_profile |grep -v '^$' ~/.bash_profile

空行不包含任何字符。

如需把一个目录下,所有*.php 文档中含有 eval 的行 过滤出 [root@localhost ~]# grep -r --include="*.php" 'eval' /data/

^和-v的区别:

grep '^[^0-9]' file 等价 grep -v '^[0-9]' file 匹配非数字字符开头的行  显示非数字开头的行

spacer.gif

wKiom1aqDtKhEHJlAAAdL-X1kNw757.png

grep '[^0-9]' file 不等价 grep -v '[0-9]' file 匹配包含非数字字符的行  显示不包含数字的行

spacer.gif

wKioL1aqDxqQVXdrAAAbHl26xbA513.png




sed:查找、替换工具

-i:直接修改原文件,默认并不修改,只是打印结果

-r:引用扩展正则表达式

-n:限制打印区域,只打印匹配的行,不加则打印全部内容且匹配的行会重复出现一次

p将前面正则表达式所匹配打印出来

  • sed -n '2p' test.txt 打印第2行

  • sed -n '/root/p' test.txt 打印包含root的行,字符串表达式得用//括起来

  • sed -nr '/root|users/p' test.txt 打印包含root或者users的行

-e:实现多个任务同时进行,也可以使用;实现

  • sed -n -e '/root/p' -e '/mail/p' test.txt 任务一打印匹配root的行,任务二打印匹配mail的行

  • sed  -n '1p;3,$p' test.txt 打印第一行和第三行到最后一行

d将前面正则表达式所匹配到删除

  • sed '/user/d' test.txt 删除包含user的行

  • sed '1,3d' test.txt 删除第1行到第3行

替换字符串和vim编辑器中的方式相同,s是替换的意思,g是全局的意思,/可以用#@代替

sed '4,$s/word1/word2/g' test.txt 从第4行开始将全文中的word1替换成word2

删除字符串

sed 's/word1//g' test.txt

调换2个字符串的位置

sed -r 's/(word1)(.*)(word2)/\3\2\1/'    1对应第一个小括号,2对应第一个小括号,3对应第一个小括号。

打印某行到某行的内容

sed -n '/word1/,/word2/'p filename 打印word1到word2的行

调换/etc/passwd的第一段和最后一段

sed -r 's/(^[^:]+)(:.*:)([^:]+$)/\3\2\1/g' /etc/passwd


awk:根据预设的分隔符和表达式,对相应区域进行处理并显示

gawk 是一个模式扫描及处理语言。缺省情况下它从标准输入读入并写至标准输出。awk可使用变量、关系运算符、if关键词


使用方法:awk '{pattern + action}' {filenames}

尽管操作可能会很复杂,但语法总是这样,其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组; pattern就是要表示的正则表达式。

变量

  • $n:表示分段后的区域,$1表示第一段,$0表示整行

  • OFS:指定通用分隔符,用于处理结果的显示

  • NF:该行分段后的区域数量,$NF表示该行最后一段

  • NR:当前处理记录是已处理文件中的第几行(当有多个文件对象时)

  • FNR:当前处理记录是所属文件中的第几行

关系运算符

  • >,<,>=,<===,!=,!~

  • 比较数字时,不要加双引号

命令连接符

  • ;       执行多个任务;等价shell中的命令连接符,将多条awk命令写在一条awk命令中执行。例如awk '/root/' fruit;awk '$1 ~/admin/ {print $1}' fruit 等价 awk '/root/;$1 ~/admin/ {print $1}' fruit,也可以使用if,如awk '{if (/root/) print $0}{if ($1 ~/admin/) print $1}' fruit

  • ||      设置多个可匹配的表达式 awk '/word1/ || /word1/' fruit

  • &&  


awk '/apple/ || /3/' fruit

算术运算符    +    -    *    /    =

    给$n赋值时,需要给字符串用""而不是//

命令行方式:awk [-F  'field-separator']  'commands'  input-file(s)

-F:指定域分隔符,默认是空格

-v:引用shell变量 -v name=$shell

检索是否包含某字符串时,得用//括起;sed和awk的匹配规则如果是正则表达式而不是纯字符串则无须加//。

    [root@asus test]# awk '/apple/' fruit

可以通过指令控制打印的内容;指令如果没写,默认打印匹配的行。

匹配规则可以不写,指令必须使用{}括起来;多个指令可以根据需求用;号写在一个{}里。

[root@asus test]# cat fruit

apple 3 46

banana 3 33

peach 6 43

pear 4 65

strawberry 6 44

watermelon 2 100

cherry 7 100

[root@asus test]# awk -F ' ' '$1=="pear" || $1 ~/water/ {print $1"¥"$2*$3}' fruit

pear¥260

watermelon¥200

[root@asus test]# awk -F ' ' '{if($1=="pear" || $1 ~/water/) print $1"¥"$2*$3}' fruit  

pear¥260

watermelon¥200

[root@asus test]# awk -F ' ' '$1=="pear" || $1 ~/water/ {$4=$2*$3;print $1"="$4"¥"}' fruit 
pear=260¥
watermelon=200¥

[root@asus test]# awk -F " " '$1=="pear" || $1 ~/water/ {OFS="-";$4=$2*$3;print NR,$1"="$4"¥"}' fruit

4-pear=260¥

6-watermelon=200¥

[root@asus test]# 

需要注意的是,没有设置匹配规则时,每个{}里的指令都会执行;反之,如果设置了匹配规则且有多个{指令}时,当表达式匹配到相应内容时,第一个{}里的指令才会执行,否则,只执行第一个{}后面的指令。简而言之,就是当表达式生效时,第一个{}才会执行

[root@asus tesst]# awk -F " " '$1=="pear" || $1 ~/water/ {OFS="-"}{$4=$2*$3;print NR,$1"="$4"¥"}' fruit  

1 apple=138¥

2 banana=99¥

3 peach=258¥

4-pear=260¥

5-strawberry=264¥

6-watermelon=200¥

7-cherry=700¥

[root@asus test]#

所以,一般情况下最好将指令写在同一个{}内。

可以使用END指定{指令}直到最后才执行 [root@localhost ~]# awk -F ':' '{(tot=tot+$3)}; END {print tot}' 1.txt


awk想打印字符串得加双引号,如果包含特殊字符就得将他用 单引号 双引号 特俗字符 双引号 单引号括起来

 如:awk '{print "This is a '"'"'"$1}' filename 


grep 是专门用于文本检索的文本编辑工具;sed是tr的升级,可以删除、打印匹配的行,替换、删除字符串;awk是cut的升级,不仅可以以行为单位,还可以将行分段,以域为单位进行检索、编辑,还可以控制域输出,它类似一种数据库操作语言。grep使用-E参数,sed使用-r参数,而awk使用--posix参数就可以使用扩展表达式符



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章