awk、sed、grep文本处理(十四)

本文介绍了如何使用sed命令删除指定范围的文本(如error和3333之间的内容),并探讨了多种方法,包括awk替代、多行注释、区间操作和字符串替换等。还提及了解决grep中lookbehind限制的问题以及使用Perl进行更灵活的操作。
摘要由CSDN通过智能技术生成

一、sed 删除指定范围的文本内容

在这里插入图片描述

111111:aaaaa
222222:bbbbb
error
33333:ccccc

44444:ddddd

error
55555:eeeee
rrrrr:oooo

方法一:

#作者:马龙帅。  按照以前学的 /error/,/3333/d;q是没用的。 要使用sed的标签功能和模式空间。  
#这个用awk做的话,逻辑会更清晰,从error开始读取,并不断追加到变量中,遇到3333就清空变量,遇到最后一行,就输出,虽然sed命令的逻辑也是
sed '/error/{:x;N;/3333/!{bx};d}' 1.txt

#但这个写法仅限于上面的文本内容。如果有多个error...3333文本。会干掉第一个error与3333直接的全部内容

参考:http://blog.chinaunix.net/uid-639516-id-2692525.html
https://www.cnblogs.com/f-ck-need-u/p/7499309.html#1-sed- 《6.sed中感叹号取反的弯弯绕绕》
https://www.cnblogs.com/f-ck-need-u/p/7478188.html 《3.7 Commands for ‘sed’ gurus(大师级的sed命令)》

方法二:

steven的解法
文本变成:

111111:aaaaa
222222:bbbbb
error
33333:ccccc

44444:ddddd

error
55555:eeeee
rrrrr:oooo

111111:aaaaa
222222:bbbbb
error
33333:ccccc

44444:ddddd

error
55555:eeeee
rrrrr:oooo
#替换法最简单,替换法还适合你说的有多个这种error - 333的段,加个g修饰符就行了。
sed -r '/error/{N;/333/d}' 1.txt

perl -0pe 's#error\n333\N*\n##gs' 1.txt
perl -0nE'print split/error\n333.*\n/' 1.txt

#grep 回溯控制 ,但由于-o 参数,导致原先的格式会有变化。
grep -Poz 'error\n333.*(*SKIP)(.*F)|.*' 1.txt

注:这里可以配合《awk、sed、grep文本处理(十 二)》的 “二、取消tomcat的server.xml的注释模块” ,加深印象

另一个文本例子:文本中有多个a标签,只删除含有xyz的

<a>
b
</a >
<a>
xyz
</a >
<a>
c
</a >

处理方法:

sed -r '/<a>/{N;N;/xyz\n<\/a >/d}' 2.txt

perl -0pe 's#<a>\nxyz\N*\n<\/a >##gs' 2.txt
#steven的写法
perl -0pe 's#<a>((?!</a >).)*?xyz((?!</a>).)*?</a >\n##s' 2.txt

#注意如果写漏/写错的话,最终效果会有所不同,如perl -0pe 's#<a>((?!</a>).)*?xyz((?!</a>).)*?</a >\n##s' 2.txt

二、sed 匹配多行,然后加上#注释

匹配 5555~空格之间的内容,然后在行首加上#注释

1111
55555
333

444

5555
66666
7777
8888

9999
#匹配范围内容然后加上注释
sed -e '/5/,/^$/ s/^/##/' 1.txt
#取消刚才的 # 注释
sed -e '/##/,/##$/ s/##//' 2.txt

三、输出111111这行前面的所有行

i11111

up up up

56
111111
456

#@dsdsa
dffas
down down
awk '/111111/{p=1}!p' 1.txt
awk '/111111/{exit}1' 1.txt

效果反之:
awk '/111111/{p=1}p' 1.txt

其他拓展:
在这里插入图片描述

四、echo “AA=aa BB=bb CC=cc” 需要提取到 aa bb cc

在这里插入图片描述

echo "AA=aa BB=bb CC=cc" | grep -oP "(?<==).*?[^ ]+"
echo "AA=aa BB=bb CC=cc" | grep -oP "(?<==).*?[^ ]+" | xargs

五、grep: lookbehind assertion is not fixed length 问题

只用grep处理,取出unset($_GET[‘onlybody’]);
文本内容:

 793                         $confirmURL = $this->createLink('bug', 'view', "id=$task->fromBug");
 794                         unset($_GET['onlybody']);
 795                         $cancelURL  = $this->createLink('task', 'view', "taskID=$taskID");

这里碰到了个问题。grep: lookbehind assertion is not fixed length
在这里插入图片描述
经过和Steven大佬交流后得知。PCRE流派现在只是实验性的增加负向零宽的无限量词,PCRE流派的用\K
就是说(?<=)和(?<!)这种lookbehind里不能有+,*这样的不定长度的量词,所以要用别的方法来代替。
在这里插入图片描述
JS流派的支持负向带有 无限 的量词
在这里插入图片描述

grep -oP "794\s+\K.*" 1.txt

grep -oP "(?<=794)\s+\K.*" 1.txt

参考:https://blog.csdn.net/weixin_38553453/article/details/112315919

六、求个awk区间统计的方法 ,小于1 1-3 大于3的区间个数

文本:

[root@jzhx54 logs]# cat test
1.01  aa
1.02  aa
2.03  bb
1.03  bb
3.10  aa
[root@jzhx54 logs]# cat testa
aa 1-3 2
aa >3 1
bb 1-3 2

steven:
在这里插入图片描述

七、如下要求:

大佬们来写个shell ,数据如下:
10.12.13
  "sdb        1   sda        1"
--
10.12.14
  "sdd        1   sdb        0   sdc        1   sda        0"
--
10.12.15
  "sda        1"
--

效果:
10.12.13 sdb 1 sda 1 
10.12.14 sdd 1 sdb 1 sdc 1 sda 1
10.12.15 sda 1

解法:

#sed:
sed  -r 's#"##g;s#-##g;/^$/d;s#^ +##g' 1.txt  |  sed -n '{N;s/\n/\t/p}'
cat test.txt | grep -ve "--" | sed -n '{N;s/\n/\t/p}' | sed 's/"//g'

在这里插入图片描述

perl:
在这里插入图片描述
awk:
在这里插入图片描述

八、shell排序数字(从小到大)

$ cat 1.txt
10,1,20,22,2,3,33,30

答:
#cat 1.txt | xargs -n 1 -d "," | sort | xargs | sed -r 's# #,#g'
cat 1.txt | xargs -n 1 -d "," | sort -n | xargs | sed -r 's# #,#g'

#去重并排序的写法
cat 1.txt | xargs -n 1 -d ","  | sort -k 1,1 -u -n | xargs |  sed -r 's# #,#g'

在这里插入图片描述

九、匹配文本中开头的中文字符

美国California州San
美国Washington州Seattle
加拿大Ontario省Brampton
grep -oP "([一-龻])+[^A-Za-z]" 1.txt
#by 行云流水
grep -Po "(?<=^)\W+(?=.*)"  1.txt

在这里插入图片描述

十、awk使用双引号的用法 和 ssh远程执行指令执行单/双引号区别。

awk "{print \$1\":\"\$2}" 1.txt

#下面的ssh 最外层的用单引号和用双印执行指令,他是有区别的!!
ssh  root@192.168.1.100 'docker image | grep ^192 | awk "NR>2 {print \$1\":\"\$2}"'

在这里插入图片描述

参考:https://www.jianshu.com/p/07fa6bed8ffb 《awk中单双引号的区别》
https://askubuntu.com/questions/475243/why-does-using-double-quotes-to-enclose-awks-action-statements-produce-differen
在这里插入图片描述

参考:
http://t.zoukankan.com/hzcya1995-p-13349090.html 《ssh 执行单引号和双引号问题》
https://www.cnblogs.com/ybyqjzl/p/10466230.html 《远程执行命令之单双引号、转义符号问题》
在这里插入图片描述

十一、sed在最后一个5.5后面 加入2222 不在每一行

#文本内容:
4.4.2
5.5.0
5.5.1
5.5.2
#steven & mrqiao
perl -0pe's#.*5\.5\N*\n\K#222\n#s' file

sed '1h;1!H;$!d;x;s/.*5\.5[^\n]*/&\n222/'

sed '/5\.5[^\n]*/,$!b;//{x;//p;g};//!H;$!d;x;s//&\n222/'

在这里插入图片描述
参考:https://www.thinbug.com/q/37909388 《最后一次与sed匹配后追加行》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值