一、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直接的全部内容
《6.sed中感叹号取反的弯弯绕绕》
《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
六、求个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}"'
《ssh 执行单引号和双引号问题》
《远程执行命令之单双引号、转义符号问题》
十一、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/'