第9章 正则 扩展

//扩展一//
第14章 正则表达式 http://www.apelearn.com/study_v2/chapter14.html
grep
语法: grep [-cinvABC] 'word' filename
-c :打印符合要求的行数
-i :忽略大小写
-n :在输出符合要求的行的同时连同行号一起输出
-v :打印不符合要求的行
-A :后跟一个数字(有无空格都可以),例如 –A2则表示打印符合要求的行以及下面两行
-B :后跟一个数字,例如 –B2 则表示打印符合要求的行以及上面两行
-C :后跟一个数字,例如 –C2 则表示打印符合要求的行以及上下各两行

1.过滤出带有某个关键词的行并输出行号
grep -n 'root' /etc/passwd
2.过滤不带有某个关键词的行,并输出行号
grep -nv 'nologin' /etc/passwd
3.过滤出所有包含数字的行
grep '[0-9]' /etc/inittab
4.过滤出所有不包含数字的行
grep -v '[0-9]' /etc/inittab
5.把所有以 ‘#’ 开头的行去除
grep -v '^#' /etc/inittab
6.去除所有空行和以 ‘#’ 开头的行
grep -v '^#' /etc/crontab |grep -v '^$'
在正则表达式中, “^” 表示行的开始, “$” 表示行的结尾,那么空行则可以用 “^$” 表示
7.过滤任意一个字符与重复字符
grep 'r..o' /etc/passwd
8.指定要过滤字符出现的次数
grep 'o{2}' /etc/passwd
egrep
1.筛选一个或一个以上前面的字符
egrep 'o+' test.txt
2.筛选零个或一个前面的字符
egrep 'o?' test.txt
3.筛选字符串1或者字符串2
egrep 'aaa|111|ooo' test.txt
4.egrep中( )的应用
egrep 'r(oo|at)o' test.txt
用( )表示一个整体,例如(oo)+就表示1个 ‘oo’ 或者多个 ‘oo’
egrep '(oo)+' test.txt
sed工具的使用
grep实现的只是查找功能,而它却不能实现把查找的内容替换掉。sed工具以及下面要讲的awk工具就能实现把替换的文本输出到屏幕上的功能了,而且还有其他更丰富的功能。sed和awk都是流式编辑器,是针对文档的行来操作的。
1.打印某行
sed -n 'n'p filename 单引号内的n是一个数字,表示第几行:
sed -n '1,$'p filename 把所有行都打印出来可以使用
2.打印包含某个字符串的行
sed -n '/root/'p test.txt
3.-e可以实现多个行为
sed -e '1'p -e '/111/'p -n test.txt
4.删除某行或者多行
sed '1,3'd test.txt
‘d’ 这个字符就是删除的动作了,不仅可以删除指定的单行以及多行,而且还可以删除匹配某个字符的行,另外还可以删除从某一行一直到文档末行。
5.替换字符或字符串
sed '1,2s/ot/to/g' test.txt
sed 's#ot#to#g' test.txt
‘s’ 就是替换的命令, ‘g’ 为本行中全局替换,如果不加 ‘g’ 只换该行中出现的第一个。除了可以使用 ‘/’ 作为分隔符外,还可以使用其他特殊字符例如 ‘#’ 或者 ‘@’ 都没有问题。
6.调换两个字符串的位置
sed 's/(rot)(.)(bash)/\3\2\1/' test.txt
用 () 把所想要替换的字符括起来成为一个整体,因为括号在sed中属于特殊符号,所以需要在前面加脱意字符 ‘’, 替换时则写成 ‘1’, ‘‘2’, ‘‘3’ 的形式。除了调换两个字符串的位置外,还常常用到在某一行前或者后增加指定内容。
sed 's/^.
$/123&/' test.txt
7.直接修改文件的内容
sed -i 's/ot/to/g' test.txt
这个命令可以直接把文件修改.

练习:把/etc/passwd 复制到/root/test.txt,用sed打印所有行
打印test.txt的3到10行
打印test.txt 中包含 ‘root’ 的行
删除test.txt 的15行以及以后所有行
删除test.txt中包含 ‘bash’ 的行
替换test.txt 中 ‘root’ 为 ‘toor’
替换test.txt中 ‘/sbin/nologin’ 为 ‘/bin/login’
删除test.txt中5到10行中所有的数字
删除test.txt 中所有特殊字符(除了数字以及大小写字母)
把test.txt中第一个单词和最后一个单词调换位置
把test.txt中出现的第一个数字和最后一个单词替换位置
把test.txt 中第一个数字移动到行末尾
在test.txt 20行到末行最前面加 ‘aaa:’
阿铭希望你能尽量多想一想,答案只是用来作为参考的。
sed习题答案

  1. /bin/cp /etc/passwd /root/test.txt ; sed -n '1,$'p test.txt
  2. sed -n '3,10'p test.txt
  3. sed -n '/root/'p test.txt
  4. sed '15,$'d test.txt
  5. sed '/bash/'d test.txt
  6. sed 's/root/toor/g' test.txt
  7. sed 's#sbin/nologin#bin/login#g' test.txt
  8. sed '5,10s/[0-9]//g' test.txt
  9. sed 's/[^0-9a-zA-Z]//g' test.txt
  10. sed 's/(^[a-zA-Z][a-zA-Z])([^a-zA-Z].)([^a-zA-Z])([a-zA-Z][a-zA-Z]*$)/\4\2\3\1/' test.txt
  11. sed 's#([^0-9][^0-9])([0-9][0-9])([^0-9].)([^a-zA-Z])([a-zA-Z][a-zA-Z]$)#\1\5\3\4\2#' test.txt
  12. sed 's#([^0-9][^0-9])([0-9][0-9])([^0-9].*$)#\1\3\2#' test.txt
  13. sed '20,$s/^.*$/aaa:&/' test.txt
    awk工具的使用
    awk比sed更加强大,它能做到sed能做到的,同样也能做到sed不能做到的。awk工具其实是很复杂的。
    1.截取文档中的某个段
    head -n2 /etc/passwd |awk -F ':' '{print $1}'
    head -n2 test.txt |awk -F':' '{print $0}'
    -F 选项的作用是指定分隔符,如果不加-F指定,则以空格或者tab为分隔符。 Print为打印的动作,用来打印出某个字段。$1为第一个字段,$2为第二个字段,依次类推,有一个特殊的那就是$0,它表示整行。
    注意awk的格式,-F后紧跟单引号,然后里面为分隔符,print的动作要用 { } 括起来,否则会报错。print还可以打印自定义的内容,但是自定义的内容要用双引号括起来。
    head -n2 test.txt |awk -F':' '{print $1"#"$2"#"$3"#"$4}'
    2.匹配字符或字符串
    awk '/oo/' test.txt
    awk -F ':' '$1 ~/oo/' test.txt
    可以让某个段去匹配,这里的’~’就是匹配的意思
    awk -F ':' '/root/ {print $1,$3} /test/ {print $1,$3}' /etc/passwd
    还可以多次匹配,如上例中匹配完root,再匹配test,它还可以只打印所匹配的段。
    3.条件操作符
    awk -F ':' '$3=="0"' /etc/passwd
    awk中是可以用逻辑符号判断的,比如 ‘==’ 就是等于,也可以理解为 ‘精确匹配’ 另外也有 >, ‘>=, ‘<, ‘<=, ‘!= 等等,值得注意的是,在和数字比较时,若把比较的数字用双引号引起来后,那么awk不会认为是数字,而认为是字符,不加双引号则认为是数字。
    awk把所有的数字当作字符来对待.
    awk -F ':' '$3<$4' /etc/passwd
    != 为不匹配,除了针对某一个段的字符进行逻辑比较外,还可以两个段之间进行逻辑比较。
    awk -F ':' '$3>"5" && $3<"7"' /etc/passwd
    awk -F ':' '$3>"5" || $7=="/bin/bash"' /etc/passwd
    另外还可以使用 && 和 || 表示 “并且” 和 “或者” 的意思。
    4.awk的内置变量
    awk常用的变量有:
    NF :用分隔符分隔后一共有多少段
    NR :行数
    head -n3 /etc/passwd | awk -F ':' '{print NF}'
    head -n3 /etc/passwd | awk -F ':' '{print $NF}'
    NF 是多少段,而$NF是最后一段的值, 而NR则是行号。
    5.awk中的数学运算
    awk可以把段值更改
    head -n 3 /etc/passwd |awk -F ':' '$1="root"';
    当然还可以计算某个段的总和
    awk -F ':' '{(tot=tot+$3)}; END {print tot}' /etc/passwd

练习:
用awk 打印整个test.txt (以下操作都是用awk工具实现,针对test.txt)
查找所有包含 ‘bash’ 的行
用 ‘:’ 作为分隔符,查找第三段等于0的行
用 ‘:’ 作为分隔符,查找第一段为 ‘root’ 的行,并把该段的 ‘root’ 换成 ‘toor’ (可以连同sed一起使用)
用 ‘:’ 作为分隔符,打印最后一段
打印行数大于20的所有行
用 ‘:’ 作为分隔符,打印所有第三段小于第四段的行
用 ‘:’ 作为分隔符,打印第一段以及最后一段,并且中间用 ‘@’ 连接 (例如,第一行应该是这样的形式 'root@/bin/bash‘ )
用 ‘:’ 作为分隔符,把整个文档的第四段相加,求和
awk习题答案

  1. awk '{print $0}' test.txt
  2. awk '/bash/' test.txt
  3. awk -F':' '$3=="0"' test.txt
  4. awk -F':' '$1=="root"' test.txt |sed 's/root/toor/'
  5. awk -F':' '{print $NF}' test.txt
  6. awk -F':' 'NR>20' test.txt
  7. awk -F':' '$3<$4' test.txt
  8. awk -F':' '{print $1"@"$NF}' test.txt
  9. awk -F':' '{(sum+=$4)}; END {print sum}' test.txt

//扩展二//
(1)打印某行到某行之间的内容http://ask.apelearn.com/question/559
sed -n '/[abcfd]/,/[rty]/p' test 截取[abcfd]到[rty]间的内容
(2)sed转换大小写 http://ask.apelearn.com/question/7758
sed中,使用\u表示大写,\l表示小写

  1. 把每个单词的第一个小写字母变大写:sed 's/\b[a-z]/\u&/g' filename
  2. 把所有小写变大写:sed 's/[a-z]/\u&/g' filename
  3. 大写变小写:sed 's/[A-Z]/\l&/g' filename
    (3)sed在某一行最后添加一个数字http://ask.apelearn.com/question/288
    (4)删除某行到最后一行 http://ask.apelearn.com/question/213
    sed '/c/{p;:a;N;$!ba;d}' test
    定义一个标签a,匹配c,然后N把下一行加到模式空间里,匹配最后一行时,才退出标签循环,然后命令d,把这个模式空间里的内容全部清除。
    if 匹配"c"
    :a
    追加下一行
    if 不匹配"$"
    goto a
    最后退出循环,d命令删除。
    (5)打印1到100行含某个字符串的行 http://ask.apelearn.com/question/1048
    sed指定行范围匹配 sed -n '1,100{/abc/p}' 1.txt
    //扩展三//
    awk 用法(使用入门) http://www.cnblogs.com/emanlee/p/3327576.html
    //扩展四//
    awk 中使用外部shell变量http://ask.apelearn.com/question/199

awk 合并一个文件 http://ask.apelearn.com/question/493
awk 'NR==FNR{a[$1]=$2}NR>FNR{print $0,a[$1]}' 1.txt 2.txt
解释:把两个文件中,第一列相同的行合并到同一行中。
NR表示读取的行数, FNR表示读取的当前行数,大家可以运行这个命令 awk '{print NR,FNR}' 1.txt 2.txt,比较NR和FNR,所以其实NR==FNR 就表示读取1.txt的时候。 同理NR>FNR表示读取2.txt的时候
数组a其实就相当于一个map。
把一个文件多行连接成一行 http://ask.apelearn.com/question/266
a=cat file;echo $a
awk '{printf("%s ",$0)}' file // %s 后记得要有一空格,否则出来就是完全连在一起的,中间连空格都没有
cat file |xargs
awk中gsub函数的使用 http://ask.apelearn.com/question/200
awk 'gsub(/www/,"abc")' /etc/passwd // passwd文件中把所有www替换为abc
awk -F ':' 'gsub(/www/,"abc",$1) {print $0}' /etc/passwd // 替换$1中的www为abc
awk 截取指定多个域为一行 http://ask.apelearn.com/question/224
用awk指定分隔符把文本分为若干段。如何把相同段的内容弄到一行?
以/etc/passwd为例,该文件以":"作为分隔符,分为了7段。
for i in seq 1 7
do
awk -F ':' -v a=$i '{printf $a " "}' /etc/passwd
echo
done
过滤两个或多个关键词 http://ask.apelearn.com/question/198
grep -E '123|abc' filename // 找出文件(filename)中包含123或者包含abc的行
egrep '123|abc' filename //用egrep同样可以实现
awk '/123|abc/' filename // awk 的实现方式
用awk生成以下结构文件 http://ask.apelearn.com/question/5494
awk用print打印单引号 http://ask.apelearn.com/question/1738
比较绕,不用死记硬背,以后用的时候,稍微多试几次就出来了。
awk 'BEGIN{print "a'"'"'s"}' //不用脱义,就多写几个单引号、双引号
awk 'BEGIN{print "a'\''s"}' //用脱义,脱义的是单引号
awk 'BEGIN{print "a\"s"}' //用脱义,脱义的是双引号
把两个文件中相同的行合并成一行 http://ask.apelearn.com/question/945
paste filename1 filename2
如果,你想在两个文件连接处用一个指定的字符连接,还可以用-d来指定
paste -d '+' a.txt b.txt

转载于:https://blog.51cto.com/iammalt/2307631

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值