Linux sed实战

简介: Linux sed实战

一、替换

79965959159c406485fe2e08a7870bd0.png

查找并替换时,sed中分隔符号不一定要使用/ ,可以使用@ #,仅当查找时不能使用其他分隔符


例如

[root@ninesun example]# cat -n a.log 
     1  dsd
     2  /etc/hosts
     3  
[root@ninesun example]# sed -r 's#/etc/hosts#/var/lib/hosts#g' a.log 
dsd
/var/lib/hosts

1、全局替换shell中的某个字符。

需要使用 -i参数才会真正修改文件,该操作不会再屏幕上返回结果。


匹配test.sh中的vmstatGene行,并将vmstatGene_169全局替换为vmstatGene_122,末尾不加g则替换第一次出现匹配关键字的位置。

sed -i '/vmstatGene/s@vmstatGene_169@vmstatGene_122@g' test.sh

ansible 替换crontab文件中关键字。可以结合管道操作匹配到的多个文件,


例如find match到多个shell

[root@gptest01 scripts]# find /home/scripts/ -type f -path "*.sh"
/home/scripts/formatVmstat_start.sh
/home/scripts/redis/insertJgeCnt.sh
/home/scripts/redis/evaluateMem.sh
/home/scripts/redis/evaluateHisOpeMem.sh
/home/scripts/redis/evaluateResult.sh
/home/scripts/redis/insertHistory.sh
/home/scripts/redis/insertResult.sh
/home/scripts/redis/del.sh
/home/scripts/redis/inersertOpehisKey.sh
/home/scripts/redis/istAll.sh
/home/scripts/formatVmstat_eth0.sh
/home/scripts/formatVmstat_bond1.sh
/home/scripts/formatVmstat_bak.sh

ansibe 批量替换

[root@gptest01 scripts]# ansible 10.50.10.172 -m shell -a  "find /var/spool/cron -name "root"|xargs sed -i '/vmstat_1/s@vmstat_172@vmstatGene_172@'"
[root@gptest01 scripts]# ansible 10.50.10.173 -m shell -a  "time sed -i '/vmstat_1/s@vmstat_173@vmstatGene_173@' /var/spool/cron/root"

2、正则匹配空行并删除  

删除空白行。

sed  '/^$/p' gpdb-2020-05-23_000000.csv 
2020-05-23 21:56:14.524927 CST,"gpadmin","qmstst",p2588,th-625846464,"[local]",,2020-05-23 21:56:14 CST,0,,,seg-1,,,,sx1,"WARNING","01000","time constraints added on superuser role",,,,,,,0,,"auth.c",2966,
2020-05-23 21:56:14.525134 CST,"gpadmin","qmstst",p2588,th-625846464,"[local]",,2020-05-23 21:56:14 CST,0,,,seg-1,,,,sx1,"FATAL","3D000","database ""qmstst"" does not exist",,,,,,,0,,"postinit.c",956,
2020-05-23 21:56:22.618282 CST,"gpadmin","postgres",p2975,th-625846464,"[local]",,2020-05-23 21:56:22 CST,0,,,seg-1,,,,sx1,"WARNING","01000","time constraints added on superuser role",,,,,,,0,,"auth.c",2966,
2020-05-23 21:56:22.619526 CST,"gpadmin","postgres",p2975,th-625846464,"[local]",,2020-05-23 21:56:22 CST,0,,,seg-1,,,,sx1,"FATAL","57P03","System was started in master-only utility mode - only utility mode connections are allowed",,,,,,,0,,"postinit.c",1142,
[root@gptest01 pg_log]# sed  '/^$/d' gpdb-2020-05-23_000000.csv 
2020-05-23 21:56:14.524927 CST,"gpadmin","qmstst",p2588,th-625846464,"[local]",,2020-05-23 21:56:14 CST,0,,,seg-1,,,,sx1,"WARNING","01000","time constraints added on superuser role",,,,,,,0,,"auth.c",2966,
2020-05-23 21:56:14.525134 CST,"gpadmin","qmstst",p2588,th-625846464,"[local]",,2020-05-23 21:56:14 CST,0,,,seg-1,,,,sx1,"FATAL","3D000","database ""qmstst"" does not exist",,,,,,,0,,"postinit.c",956,
2020-05-23 21:56:22.618282 CST,"gpadmin","postgres",p2975,th-625846464,"[local]",,2020-05-23 21:56:22 CST,0,,,seg-1,,,,sx1,"WARNING","01000","time constraints added on superuser role",,,,,,,0,,"auth.c",2966,
2020-05-23 21:56:22.619526 CST,"gpadmin","postgres",p2975,th-625846464,"[local]",,2020-05-23 21:56:22 CST,0,,,seg-1,,,,sx1,"FATAL","57P03","System was started in master-only utility mode - only utility mode connections are allowed",,,,,,,0,,"postinit.c",1142,

3、替换经典案例(正则)

要点: sed 结合正则替换一个和多个空格.


替换前是这样的:

go_gc_duration_seconds{quantile="0"} 0.000158734
go_gc_duration_seconds{quantile="0.25"} 0.000242638
go_gc_duration_seconds{quantile="0.5"} 0.000272045
go_gc_duration_seconds{quantile="0.75"} 0.000311615
go_gc_duration_seconds{quantile="1"} 0.005289956
go_gc_duration_seconds_sum 72.816662569
go_gc_duration_seconds_count 221774
go_goroutines 12
go_memstats_alloc_bytes 1.07251032e+08
go_memstats_alloc_bytes_total 9.151138705928e+12

替换后:

192.168.200.23|2020-06-25 19:22:09|go_gc_duration_seconds{quantile="0"}|0.000158734
192.168.200.23|2020-06-25 19:22:09|go_gc_duration_seconds{quantile="0.25"}|0.000242638
192.168.200.23|2020-06-25 19:22:09|go_gc_duration_seconds{quantile="0.5"}|0.000272045
192.168.200.23|2020-06-25 19:22:09|go_gc_duration_seconds{quantile="0.75"}|0.000311615
192.168.200.23|2020-06-25 19:22:09|go_gc_duration_seconds{quantile="1"}|0.005289956
192.168.200.23|2020-06-25 19:22:09|go_gc_duration_seconds_sum|72.816662569
192.168.200.23|2020-06-25 19:22:09|go_gc_duration_seconds_count|221774
192.168.200.23|2020-06-25 19:22:09|go_goroutines|12
192.168.200.23|2020-06-25 19:22:09|go_memstats_alloc_bytes|1.07251032e+08
192.168.200.23|2020-06-25 19:22:09|go_memstats_alloc_bytes_total|9.151138705928e+12

这是为了将非结构化的数据转换为结构化的数据并将其持久化到数据库。


先看一下这个例子

rabbmitMq]# cat tst.log |sed 's/ /|/'|awk '{print strftime("%Y-%m-%d %H:%M:%S"),$0}'|sed 's/[ ][ ]*/|/g'|head
2020-06-25|22:23:20|go_gc_duration_seconds{quantile="0"}|0.000158734
2020-06-25|22:23:20|go_gc_duration_seconds{quantile="0.25"}|0.000242638
2020-06-25|22:23:20|go_gc_duration_seconds{quantile="0.5"}|0.000272045
2020-06-25|22:23:20|go_gc_duration_seconds{quantile="0.75"}|0.000311615
2020-06-25|22:23:20|go_gc_duration_seconds{quantile="1"}|0.005289956
2020-06-25|22:23:20|go_gc_duration_seconds_sum|72.816662569
2020-06-25|22:23:20|go_gc_duration_seconds_count|221774
2020-06-25|22:23:20|go_goroutines|12
2020-06-25|22:23:20|go_memstats_alloc_bytes|1.07251032e+08
2020-06-25|22:23:20|go_memstats_alloc_bytes_total|9.151138705928e+12

可以看到时间的空格那里也被|隔开,是我们不想要的。如何处理这个时间格式中的空格呢?


这里采用一种迂回的方式来完成。


's/|/ /' 替换每行首个|为空格,即完成了需求。

~]# cat /home/scripts/tune/rabbmitMq/tst.log |sed 's/ /|/'|awk '{print strftime("%Y-%m-%d %H:%M:%S"),$0}'|sed 's/[ ]/|/g'|sed 's/|/ /'|head
2020-06-26 10:35:28|go_gc_duration_seconds{quantile="0"}|0.000158734
2020-06-26 10:35:28|go_gc_duration_seconds{quantile="0.25"}|0.000242638
2020-06-26 10:35:28|go_gc_duration_seconds{quantile="0.5"}|0.000272045
2020-06-26 10:35:28|go_gc_duration_seconds{quantile="0.75"}|0.000311615
2020-06-26 10:35:28|go_gc_duration_seconds{quantile="1"}|0.005289956
2020-06-26 10:35:28|go_gc_duration_seconds_sum|72.816662569
2020-06-26 10:35:28|go_gc_duration_seconds_count|221774
2020-06-26 10:35:28|go_goroutines|12
2020-06-26 10:35:28|go_memstats_alloc_bytes|1.07251032e+08
2020-06-26 10:35:28|go_memstats_alloc_bytes_total|9.151138705928e+12

最后再把ip 添加到行首或者行尾即可。

~]# cat /home/scripts/tune/rabbmitMq/tst.log |sed 's/ /|/'|awk '{print strftime("%Y-%m-%d %H:%M:%S"),$0}'|sed 's/[ ][ ]*/|/g'|sed 's/|/ /'|sed 's/^/'192.168.200.23'|/g'|head -n 10
192.168.200.23|2020-06-26 10:41:35|go_gc_duration_seconds{quantile="0"}|0.000158734
192.168.200.23|2020-06-26 10:41:35|go_gc_duration_seconds{quantile="0.25"}|0.000242638
192.168.200.23|2020-06-26 10:41:35|go_gc_duration_seconds{quantile="0.5"}|0.000272045
192.168.200.23|2020-06-26 10:41:35|go_gc_duration_seconds{quantile="0.75"}|0.000311615
192.168.200.23|2020-06-26 10:41:35|go_gc_duration_seconds{quantile="1"}|0.005289956
192.168.200.23|2020-06-26 10:41:35|go_gc_duration_seconds_sum|72.816662569
192.168.200.23|2020-06-26 10:41:35|go_gc_duration_seconds_count|221774
192.168.200.23|2020-06-26 10:41:35|go_goroutines|12
192.168.200.23|2020-06-26 10:41:35|go_memstats_alloc_bytes|1.07251032e+08
192.168.200.23|2020-06-26 10:41:35|go_memstats_alloc_bytes_total|9.151138705928e+12

总结:

awk '{print strftime("%Y-%m-%d %H:%M:%S"),$0}'      为当前行最前面添加时间。

s

使用替换模式替换相应模式


[]

匹配指定范围内的任意单个字符


*

匹配紧挨在前面的字符任意次(0,1,多次)


's/[ ][ ]*/|/g'

开启匹配模式,匹配一个空格或N个空格全局替换为 |


's/|/ /'

替换每行首个|为空格


有人想说匹配一个或N个空格为什么不直接用 s/[ ]*/|/g 呢?请看下例,可以看到如果直接使用这个表达式将0个空格的情况也包含了。

rabbmitMq]# cat tst.log |sed 's/ /|/'|awk '{print strftime("%Y-%m-%d %H:%M:%S"),$0}'|sed 's/[ ]*/|/g'|head
|2|0|2|0|-|0|6|-|2|5|2|2|:|2|8|:|0|2|g|o|_|g|c|_|d|u|r|a|t|i|o|n|_|s|e|c|o|n|d|s|{|q|u|a|n|t|i|l|e|=|"|0|"|}|||0|.|0|0|0|1|5|8|7|3|4|
|2|0|2|0|-|0|6|-|2|5|2|2|:|2|8|:|0|2|g|o|_|g|c|_|d|u|r|a|t|i|o|n|_|s|e|c|o|n|d|s|{|q|u|a|n|t|i|l|e|=|"|0|.|2|5|"|}|||0|.|0|0|0|2|4|2|6|3|8|
|2|0|2|0|-|0|6|-|2|5|2|2|:|2|8|:|0|2|g|o|_|g|c|_|d|u|r|a|t|i|o|n|_|s|e|c|o|n|d|s|{|q|u|a|n|t|i|l|e|=|"|0|.|5|"|}|||0|.|0|0|0|2|7|2|0|4|5|
|2|0|2|0|-|0|6|-|2|5|2|2|:|2|8|:|0|2|g|o|_|g|c|_|d|u|r|a|t|i|o|n|_|s|e|c|o|n|d|s|{|q|u|a|n|t|i|l|e|=|"|0|.|7|5|"|}|||0|.|0|0|0|3|1|1|6|1|5|
|2|0|2|0|-|0|6|-|2|5|2|2|:|2|8|:|0|2|g|o|_|g|c|_|d|u|r|a|t|i|o|n|_|s|e|c|o|n|d|s|{|q|u|a|n|t|i|l|e|=|"|1|"|}|||0|.|0|0|5|2|8|9|9|5|6|
|2|0|2|0|-|0|6|-|2|5|2|2|:|2|8|:|0|2|g|o|_|g|c|_|d|u|r|a|t|i|o|n|_|s|e|c|o|n|d|s|_|s|u|m|||7|2|.|8|1|6|6|6|2|5|6|9|
|2|0|2|0|-|0|6|-|2|5|2|2|:|2|8|:|0|2|g|o|_|g|c|_|d|u|r|a|t|i|o|n|_|s|e|c|o|n|d|s|_|c|o|u|n|t|||2|2|1|7|7|4|
|2|0|2|0|-|0|6|-|2|5|2|2|:|2|8|:|0|2|g|o|_|g|o|r|o|u|t|i|n|e|s|||1|2|
|2|0|2|0|-|0|6|-|2|5|2|2|:|2|8|:|0|2|g|o|_|m|e|m|s|t|a|t|s|_|a|l|l|o|c|_|b|y|t|e|s|||1|.|0|7|2|5|1|0|3|2|e|+|0|8|
|2|0|2|0|-|0|6|-|2|5|2|2|:|2|8|:|0|2|g|o|_|m|e|m|s|t|a|t|s|_|a|l|l|o|c|_|b|y|t|e|s|_|t|o|t|a|l|||9|.|1|5|1|1|3|8|7|0|5|9|2|8|e|+|1|2|

对于本例替换空格可以直接使用  's/[ ]/|/g'

~]# cat /home/scripts/tune/rabbmitMq/tst.log |sed 's/ /|/'|awk '{print strftime("%Y-%m-%d %H:%M:%S"),$0}'|sed 's/[ ]/|/g'|sed 's/|/ /'|head -n 10
2020-06-26 10:48:14|go_gc_duration_seconds{quantile="0"}|0.000158734
2020-06-26 10:48:14|go_gc_duration_seconds{quantile="0.25"}|0.000242638
2020-06-26 10:48:14|go_gc_duration_seconds{quantile="0.5"}|0.000272045
2020-06-26 10:48:14|go_gc_duration_seconds{quantile="0.75"}|0.000311615
2020-06-26 10:48:14|go_gc_duration_seconds{quantile="1"}|0.005289956
2020-06-26 10:48:14|go_gc_duration_seconds_sum|72.816662569
2020-06-26 10:48:14|go_gc_duration_seconds_count|221774
2020-06-26 10:48:14|go_goroutines|12
2020-06-26 10:48:14|go_memstats_alloc_bytes|1.07251032e+08
2020-06-26 10:48:14|go_memstats_alloc_bytes_total|9.151138705928e+12

这个表达式变得更好理解,但是通用性变差了,如果某个参数和值之间是两个空格呢?


我修改一下让其中出现两个空格的情况存在。

2020062610510358.png

这个就变成了两个||,解决这个问题的方法就是使用 's/[ ][ ]*/|/'.如下图

20200626105326255.png

这个问题曾经在处理vmstat时遇到过,处理方式和上面的方法是一样的。

20200626105502615.png

4、时间处理

格式化时间是常见的需求,应熟练掌握。

opt]# date '+%Y-%m-%d %H:%M:%S'
2022-01-03 02:27:03
opt]# date '+%Y-%m-%d %H:%M:%S' | sed 's/-//g' | sed 's/ //g' | sed 's/':'//g'
20220103022906

5、滤出html中href 元素后的网址

文本如下

<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10353166.html">Linux性能优化实战学习笔记:第二讲</a></p>
<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10802102.html">Linux性能优化实战学习笔记:第三讲</a></p>
<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10808031.html">Linux性能优化实战学习笔记:第五讲</a></p>
<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10808936.html">Linux性能优化实战学习笔记:第六讲</a></p>
<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10809642.html">Linux性能优化实战学习笔记:第七讲</a></p>
<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10811704.html">Linux性能优化实战学习笔记:第八讲</a></p>
<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10815283.html">Linux性能优化实战学习笔记:第九讲</a></p>
<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10820252.html">Linux性能优化实战学习笔记:第十讲</a></p>
<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10592001.html">Linux性能优化实战学习笔记:第十一讲</a></p>
<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10827212.html">Linux性能优化实战学习笔记:第十二讲</a></p>
<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10833109.html">Linux性能优化实战学习笔记:第十三讲</a></p>
<h2>&nbsp;二、内存性能:8讲</h2>
<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10831209.html">Linux性能优化实战学习笔记:第十五讲</a></p>
<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10832062.html">Linux性能优化实战学习笔记:第十六讲</a></p>
<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10839790.html">Linux性能优化实战学习笔记:第十七讲</a><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10804753.html"><br></a></p>
<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10833689.html">Linux性能优化实战学习笔记:第十七讲</a></p>
<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10842424.html">Linux性能优化实战学习笔记:第十八讲</a></p>
<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10353819.html">Linux性能优化实战学习笔记:第十九讲</a></p>
<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10353904.html">Linux性能优化实战学习笔记:第二十讲</a></p>
<p><a class="entrylistItemTitle" href="https://www.cnblogs.com/luoahong/p/10844808.html">Linux性能优化实战学习笔记:第二十一讲</a></p>
<h2>&nbsp;三、IO性能:10讲</h2>

主要分为两步:

1.取出href整个元素

 regExp]# more html_parse.html |awk '{print$3}'
href="https://www.cnblogs.com/luoahong/p/10353166.html">Linux性能优化实战学习笔记:第二讲</a></p>
href="https://www.cnblogs.com/luoahong/p/10802102.html">Linux性能优化实战学习笔记:第三讲</a></p>
href="https://www.cnblogs.com/luoahong/p/10808031.html">Linux性能优化实战学习笔记:第五讲</a></p>
href="https://www.cnblogs.com/luoahong/p/10808936.html">Linux性能优化实战学习笔记:第六讲</a></p>
href="https://www.cnblogs.com/luoahong/p/10809642.html">Linux性能优化实战学习笔记:第七讲</a></p>
href="https://www.cnblogs.com/luoahong/p/10811704.html">Linux性能优化实战学习笔记:第八讲</a></p>
href="https://www.cnblogs.com/luoahong/p/10815283.html">Linux性能优化实战学习笔记:第九讲</a></p>
href="https://www.cnblogs.com/luoahong/p/10820252.html">Linux性能优化实战学习笔记:第十讲</a></p>
href="https://www.cnblogs.com/luoahong/p/10592001.html">Linux性能优化实战学习笔记:第十一讲</a></p>
href="https://www.cnblogs.com/luoahong/p/10827212.html">Linux性能优化实战学习笔记:第十二讲</a></p>
href="https://www.cnblogs.com/luoahong/p/10833109.html">Linux性能优化实战学习笔记:第十三讲</a></p>
href="https://www.cnblogs.com/luoahong/p/10831209.html">Linux性能优化实战学习笔记:第十五讲</a></p>
href="https://www.cnblogs.com/luoahong/p/10832062.html">Linux性能优化实战学习笔记:第十六讲</a></p>
href="https://www.cnblogs.com/luoahong/p/10839790.html">Linux性能优化实战学习笔记:第十七讲</a><a
href="https://www.cnblogs.com/luoahong/p/10833689.html">Linux性能优化实战学习笔记:第十七讲</a></p>
href="https://www.cnblogs.com/luoahong/p/10842424.html">Linux性能优化实战学习笔记:第十八讲</a></p>
href="https://www.cnblogs.com/luoahong/p/10353819.html">Linux性能优化实战学习笔记:第十九讲</a></p>
href="https://www.cnblogs.com/luoahong/p/10353904.html">Linux性能优化实战学习笔记:第二十讲</a></p>
href="https://www.cnblogs.com/luoahong/p/10844808.html">Linux性能优化实战学习笔记:第二十一讲</a></p>


2、处理href

sed  '/^$/d' tmpHtml.html |sed 's/href="//g'|awk -F '[">]' '{print$1}'
分解:
1、先删除空行,使用 /^$/d
2、将href=" 替换为空白
3、使用awk -F '[">]' 将此为分隔符把第一列打印出来
经过以上步骤就得到了结果
 regExp]# sed  '/^$/d' tmpHtml.html |sed 's/href="//g'|awk -F '[">]' '{print$1}'
https://www.cnblogs.com/luoahong/p/10353166.html
https://www.cnblogs.com/luoahong/p/10802102.html
https://www.cnblogs.com/luoahong/p/10808031.html
https://www.cnblogs.com/luoahong/p/10808936.html
https://www.cnblogs.com/luoahong/p/10809642.html
https://www.cnblogs.com/luoahong/p/10811704.html
https://www.cnblogs.com/luoahong/p/10815283.html
https://www.cnblogs.com/luoahong/p/10820252.html
https://www.cnblogs.com/luoahong/p/10592001.html
https://www.cnblogs.com/luoahong/p/10827212.html
https://www.cnblogs.com/luoahong/p/10833109.html
https://www.cnblogs.com/luoahong/p/10831209.html
https://www.cnblogs.com/luoahong/p/10832062.html
https://www.cnblogs.com/luoahong/p/10839790.html

6、替换匹配到的字符串

需求: 批量修改/etc/ssh/sshd_conf中的配置。

1a46a9bfcbb54d128678cd006c0b6de8.png

需要将这一行的注释打开并修改为no,来优化ssh的效能。

opt]# sed -ri '/^#UseDNS/cUseDNS no' sshd_config

97c9362b949746e3a5d428c2ed77a241.png

sed 命令解析:

-r 开启扩展正则

-i 直接修改文本

^#UseDNS 匹配#UseDNS的行,

c\ 用新文本替换定位文本,一般省略\

 opt]#  sed -ri '/^#UseDNS/c\UseDNS no' sshd_config 和
 opt]#  sed -ri '/^#UseDNS/cUseDNS no' sshd_config 等价

7、忽略大小写替换

在模式空间使用 i

be31f4e6cfcb4741b14faecbf88be8f1.png

8、匹配到的行整行替换

这个需求常见于修改配置。


例如

chot.qmsrpt.version=V22.0805.01

需要将=后面的内容替换为一个新的tag.

[root@meta ~]#cat /tmp/config.test
chot.qmsrpt.version = V22.0805.01
[root@meta ~]#
[root@meta ~]#
[root@meta ~]#sed -n '/^chot.qmsrpt.version/cchot.qmsrpt.version=V22.0805.02' /tmp/config.test
chot.qmsrpt.version=V22.0805.02

二、查找

1、查找匹配到的行

-n 参数是只打印模式匹配的行,否则会打印所有。


参数p 代表pattern,标识匹配。

tmp]# sed -n '/target/p' ansible.cfg 
# prevents logging of tasks, but only on the targets, data is still logged on the master/controller
no_target_syslog = True
#no_target_syslog = False

如果是一个时间区间,则可以使用 " , "隔开时间区间过滤。

pg_log]# cat -n gpdb-2020-05-23_000000.csv 
     1  2020-05-23 21:56:14.524927 CST,"gpadmin","qmstst",p2588,th-625846464,"[local]",,2020-05-23 21:56:14 CST,0,,,seg-1,,,,sx1,"WARNING","01000","time constraints added on superuser role",,,,,,,0,,"auth.c",2966,
     2  2020-05-23 21:56:14.525134 CST,"gpadmin","qmstst",p2588,th-625846464,"[local]",,2020-05-23 21:56:14 CST,0,,,seg-1,,,,sx1,"FATAL","3D000","database ""qmstst"" does not exist",,,,,,,0,,"postinit.c",956,
     3  2020-05-23 21:56:22.618282 CST,"gpadmin","postgres",p2975,th-625846464,"[local]",,2020-05-23 21:56:22 CST,0,,,seg-1,,,,sx1,"WARNING","01000","time constraints added on superuser role",,,,,,,0,,"auth.c",2966,
     4  2020-05-23 21:56:22.619526 CST,"gpadmin","postgres",p2975,th-625846464,"[local]",,2020-05-23 21:56:22 CST,0,,,seg-1,,,,sx1,"FATAL","57P03","System was started in master-only utility mode - only utility mode connections are allowed",,,,,,,0,,"postinit.c",1142,
pg_log]# sed -n '/21:56:14.524/,/21:56:22/p' gpdb-2020-05-23_000000.csv 
2020-05-23 21:56:14.524927 CST,"gpadmin","qmstst",p2588,th-625846464,"[local]",,2020-05-23 21:56:14 CST,0,,,seg-1,,,,sx1,"WARNING","01000","time constraints added on superuser role",,,,,,,0,,"auth.c",2966,
2020-05-23 21:56:14.525134 CST,"gpadmin","qmstst",p2588,th-625846464,"[local]",,2020-05-23 21:56:14 CST,0,,,seg-1,,,,sx1,"FATAL","3D000","database ""qmstst"" does not exist",,,,,,,0,,"postinit.c",956,
2020-05-23 21:56:22.618282 CST,"gpadmin","postgres",p2975,th-625846464,"[local]",,2020-05-23 21:56:22 CST,0,,,seg-1,,,,sx1,"WARNING","01000","time constraints added on superuser role",,,,,,,0,,"auth.c",2966,
[root@gptest01 pg_log]# 

三、修改行

dea53956f175425c87579564c085bb1e.png

1、给不需要的行添加注释

对ansib 提取的结果进行处理。


&  保存查找串以便在替换串中引用


例如 s/my/**&**/  符号&代表查找串。my将被替换为**my**

 GP]# cat gplogpath.log |sed 's/^10/#&/'|sed 's/^find/#&/'
#10.50.10.169 | FAILED | rc=1 >>
#find: `/datap1[1-4]/gpseg*/pg_log/': No such file or directorynon-zero return code
#10.50.10.173 | SUCCESS | rc=0 >>
/datap11/gpseg8/pg_log/gpdb-2020-08-09_000000.csv
/datap12/gpseg9/pg_log/gpdb-2020-08-09_000000.csv
/datap13/gpseg10/pg_log/gpdb-2020-08-09_000000.csv
/datap14/gpseg11/pg_log/gpdb-2020-08-09_000000.csv
#10.50.10.171 | SUCCESS | rc=0 >>
/datap11/gpseg0/pg_log/gpdb-2020-08-09_000000.csv
/datap12/gpseg1/pg_log/gpdb-2020-08-09_000000.csv
/datap13/gpseg2/pg_log/gpdb-2020-08-09_000000.csv
/datap14/gpseg3/pg_log/gpdb-2020-08-09_000000.csv
#10.50.10.172 | SUCCESS | rc=0 >>
/datap11/gpseg4/pg_log/gpdb-2020-08-09_000000.csv
/datap12/gpseg5/pg_log/gpdb-2020-08-09_000000.csv
/datap13/gpseg6/pg_log/gpdb-2020-08-09_000000.csv
/datap14/gpseg7/pg_log/gpdb-2020-08-09_000000.csv
#10.50.10.174 | SUCCESS | rc=0 >>
/datap11/gpseg12/pg_log/gpdb-2020-08-09_000000.csv
/datap12/gpseg13/pg_log/gpdb-2020-08-09_000000.csv
/datap13/gpseg14/pg_log/gpdb-2020-08-09_000000.csv
/datap14/gpseg15/pg_log/gpdb-2020-08-09_000000.csv

其他注释方式

[root@ninesun example]# sed -r 's/(.*)/#\1/' passwd # \1 位置引用
#root:x:0:0:root:/root:/bin/bash
#bin:x:1:1:bin:/bin:/sbin/nologin
#daemon:x:2:2:daemon:/sbin:/sbin/nologin
#adm:x:3:4:adm:/var/adm:/sbin/nologin
#lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
#sync:x:5:0:sync:/sbin:/bin/sync
#shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
#halt:x:7:0:halt:/sbin:/sbin/halt
#mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
#operator:x:11:0:operator:/root:/sbin/nologin
[root@ninesun example]# 
[root@ninesun example]# 
[root@ninesun example]# sed -r 's/^/#/' passwd 
#root:x:0:0:root:/root:/bin/bash
#bin:x:1:1:bin:/bin:/sbin/nologin
#daemon:x:2:2:daemon:/sbin:/sbin/nologin
#adm:x:3:4:adm:/var/adm:/sbin/nologin
#lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
#sync:x:5:0:sync:/sbin:/bin/sync
#shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
#halt:x:7:0:halt:/sbin:/sbin/halt
#mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
#operator:x:11:0:operator:/root:/sbin/nologin
[root@ninesun example]# 
[root@ninesun example]# sed -r 's/(.*)/#&/' passwd # &代表匹配到的内容
#root:x:0:0:root:/root:/bin/bash
#bin:x:1:1:bin:/bin:/sbin/nologin
#daemon:x:2:2:daemon:/sbin:/sbin/nologin
#adm:x:3:4:adm:/var/adm:/sbin/nologin
#lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
#sync:x:5:0:sync:/sbin:/bin/sync
#shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
#halt:x:7:0:halt:/sbin:/sbin/halt
#mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
#operator:x:11:0:operator:/root:/sbin/nologin
[root@ninesun example]# 
[root@ninesun example]# 
[root@ninesun example]# sed -r '1,3s/(.*)/#&/' passwd  #1,3 行注释
#root:x:0:0:root:/root:/bin/bash
#bin:x:1:1:bin:/bin:/sbin/nologin
#daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin


如何避免重复注释呢?


将多个#替换成一个#

c36d93914a9c42479f1916f98eff22e0.png

2、 删除奇数、偶数行

efdd3162455b402b810e66eedc3d6dd1.png

3、在行中任意位置添加内容

位置引用


(.)(.)(.*) 把一行的内容分隔成三部分,第一个字符 第二个字符 其他字符. 这样就可以非常灵活(注意()位置引用只能有9个)

[root@ninesun example]# sed -r 's/(.)(.)(.*)/\1\2WWW\3/' passwd 
roWWWot:x:0:0:root:/root:/bin/bash
biWWWn:x:1:1:bin:/bin:/sbin/nologin
[root@ninesun example]# 
[root@ninesun example]# sed -r 's/(.*)(.)/\1WWW\2/' passwd 
root:x:0:0:root:/root:/bin/basWWWh
bin:x:1:1:bin:/bin:/sbin/nologiWWWn

add03e0911ca46e18a29fd5ec14742ad.png

--update 2022年6月23日14:56:52

sed -ri 's/.*swap.*/#&/' /etc/fstab

只有一个()的时候,后面引用它时可以直接用  &

16ca2ff8bc4c4ba9a06cea66782c3b19.png

sed -i '/swap/s/^/#/' fstab  # 匹配查找替换也是可以的

cea717e36ec94ee5bbb83cfc4591c83c.png

批量重命名文件

对于批量重命名文件可以使用xargs -I 也可以使用sed。相对来说sed更灵活,批量重命名是可逆的.

sed]# ls | grep test | xargs -I GG echo "mv GG ./backup/GG.back"
mv test10.sql ./backup/test10.sql.back
mv test1.sql ./backup/test1.sql.back
mv test2.sql ./backup/test2.sql.back
mv test3.sql ./backup/test3.sql.back
mv test4.sql ./backup/test4.sql.back
mv test5.sql ./backup/test5.sql.back
mv test6.sql ./backup/test6.sql.back
mv test7.sql ./backup/test7.sql.back
mv test8.sql ./backup/test8.sql.back
mv test9.sql ./backup/test9.sql.back
mv test.sql ./backup/test.sql.back
sed]# ls | grep test | sed -r 's/(.*)/mv \1 \1.back/g'
mv test10.sql test10.sql.back
mv test1.sql test1.sql.back
mv test2.sql test2.sql.back
mv test3.sql test3.sql.back
mv test4.sql test4.sql.back
mv test5.sql test5.sql.back
mv test6.sql test6.sql.back
mv test7.sql test7.sql.back
mv test8.sql test8.sql.back
mv test9.sql test9.sql.back
mv test.sql test.sql.back
[root@ninesun sed]# ls | grep test | sed -r 's/(.*)/mv \1 \1.back/g'|bash
[root@ninesun sed]# ls -l
total 48
drwxr-xr-x 2 root root 4096 Jan 13 16:26 backup
-rw-r--r-- 1 root root   61 Jan 11 11:53 test10.sql.back
-rw-r--r-- 1 root root   60 Jan 11 11:53 test1.sql.back
-rw-r--r-- 1 root root   60 Jan 11 11:53 test2.sql.back
-rw-r--r-- 1 root root   60 Jan 11 11:53 test3.sql.back
-rw-r--r-- 1 root root   60 Jan 11 11:53 test4.sql.back
-rw-r--r-- 1 root root   60 Jan 11 11:53 test5.sql.back
-rw-r--r-- 1 root root   60 Jan 11 11:53 test6.sql.back
-rw-r--r-- 1 root root   60 Jan 11 11:53 test7.sql.back
-rw-r--r-- 1 root root   60 Jan 11 11:53 test8.sql.back
-rw-r--r-- 1 root root   60 Jan 11 11:53 test9.sql.back
-rw-r--r-- 1 root root   52 Jan 11 11:34 test.sql.back

4、sed -r 读取外部文件

4ff6b01861294a1289e580e70abdbca4.png

要区分 2r和/2/r ,第一个是第二行,第二个是正则匹配2的行

5aa2e5a4b7484c5c9fd2f139e4427a01.png

5、匹配到的行写入其他文件

d1b16975ab75447abbd865da2687ebbd.png

3,$w 第三行到最后一行写入new1.txt

992f9f2dcc6a437581f81219cd12c05a.png

最佳多行

af5f63a38beb4de9a816d5e22a344977.png

6、模式空间中的a i c

  • a 行后追加
  • i 行前追加
  • c 替换行

15ba82eeab8e40ab8ca532cdb6b8b2be.png

163b2077447740a8a5ea57a8759c061d.png

7、-n 隔山打牛

有时候匹配的时候,不太好这,比如找个地方不好找,但是旁边有高楼,那就先找到高楼,再去找旁边要找的地方。

fed7d0dd5ead4c45b69d2bd6be709896.png

-n可以使用多次

66cce36713ae4b6e9d75666f5bae802b.png

多行命令

sed 命令的基础功能时, sed 命令都只是针对单行数据执行操作,但是,有时我们需要对多行的数据执行特定操作。如在文本中查找一串字符串"xxxxxxxxxxxx",它很有可能出现在两行中,每行各包含其中一部分。

[root@ninesun example]# cat sed_test.txt 
Make sure that the heap size is
set to about half the memory available
on the system and that the owner
of the process is allowed to use this
limit
[root@ninesun example]# 
[root@ninesun example]# sed '/lable/{N;s/\n/ /}' sed_test.txt 
Make sure that the heap size is
set to about half the memory available on the system and that the owner
of the process is allowed to use this
limit

wed to use this

limit

-N 将数据流中的两个文本行合并到同一个模式空间中。文本行仍然用换行符分隔

[root@ninesun example]# cat data4.txt 
On Tuesday, the Linux System
Administrator's group meeting will be held.
All System Administrators should attend.
[root@ninesun example]# sed '
> s/System Administrator/Desktop User/
> N
> s/System\nAdministrator/Desktop\nUser/
> ' data4.txt
On Tuesday, the Linux Desktop
User's group meeting will be held.
All Desktop Users should attend.

8、sed -h -H 和-g -G 写入

sed是一行一行处理文本的,将每一行写入模式空间进行处理。


如果使用了 -h -H 和-g -G则代表使用暂存空间(保持空间)和模式空间进行交互。

6173bc4bcf7d48b9836ff9662a0a4a83.png

291b8ce6d21d4feb8ddbd0cb23d58330.png

当启动sed编辑器时,暂存空间(保持空间)只有一个空行。 不是处理每行都有空行。


需求1: 第一行复制到最后一行

cd02193b5eb34b87a0a7040cb4af42ef.png

需求2: 第一行移动到最后一行


1{h;d};$G : 从模式空间取第一行覆盖写入暂存空间,然后模式空间中d删除。$G代表处理模式空间最后一行的时候从暂存空间取出第一行追加写入模式空间


如果是$g 可以看到最后一行被覆盖掉了。

c6620e71b22f4b8b872e90e41b5ce839.png

需求3: 使用第一行覆盖所有内容


'1h;2,$G' :


第一行从模式空间存入暂存空间, 模式空间输出第一行内容


模式空间中处理第二行到最后一行时,g从暂存空间取出第一行覆盖写入2,$的模式空间(是一个动态的过程一行一行处理)


如果是G就是追加写,没写入模式空间一行,就从暂存空间取回来root那一行。

7c4c2284ceb6434cba6fd295e26e56c8.png

需求4: 加倍行间距


sed 'G' data2.txt  


sed '$!G' data2.txt  去掉最后一行后的空行


sed '/^$/d ; $!G' test.log 如果文本中含有空行

9、sed对广义空行的处理

对空行的定义是处理该问题的关键.


  • ^$ 整个空行
  • \t table键空行
  • space 空行


文件内容如下:


vim下 set list可现实特殊字符


现在 TAB 键显示为 ^I,而 $显示在每行的结尾,以便你能找到可能会被你忽略的空白字符在哪里。

ef57cb1fb17245149270ae278b861bb4.png

如何打开文件中的注释行呢?

d80dd69d66f34dac88a1eaee5ceef511.png

^[ \t]*#  :以空格或table开始到#号(包括#号)出现一次或多次

example]# sed -r '/^[ \t]*#/d' space.txt 
asdasd
/etc/hosts
sdsdwqeqw

如何删除注释时同时删除空行?04fac26eac21456ba4e523fc659f4463.png

example]# sed -r '/^[ \t]*#/d; /^$/d' space.txt
example]# sed -r '/^[ \t]*($|#)/d' space.txt # 更简便

00fbd71a0461452eaa65768c4df71c37.png

fc329f612fea48c7a72670daa0860e09.png

10、sed修改ssh配置

0e32d18de917416c88c8c16889f720ab.png

掌握a\: 追加, c\ :匹配到的内容进行替换 <其中\可省略>,详情可参考1.6

11、sed使用外部变量

7722c074e2294e0885964f20d422aa01.png

12、sed实现字符串倒转

1.最简单的实现方式应该是tac。

10b5a235fd7f434ea846db50c53e841a.png

2.使用暂存空间和模式空间实现


按照如下几个步骤实现倒转:

(1) 在模式空间中放置一行;
(2) 将模式空间中的行放到保持空间中;
(3) 在模式空间中放入下一行;
(4) 将保持空间附加到模式空间后;
(5) 将模式空间中的所有内容都放到保持空间中;
(6)重复执行第(3)~(5)步,直到所有行都反序放到了保持空间中;
(7) 提取并打印行。

6edbb09717844c5c84d8b75d2589eae4.png

example]# sed -r '1!G; $!h; $!d' reverse.txt

3a71e98735bd455683c3f2424b702a92.png

如果不使用-r


-n 在处理时不打印行

sed -n '{1!G ; h ; $p }' reverse.txt

d7e0a62b73dc47b5b4f216bf0043182a.png

--update 2022年3月5日14:19:47


这个过程确实不是很好想,可以使用sedsed来debug这个命令。


例如

compare the normal sed run and the sedsed debug run for a script to reverse the line order (similar to Unix tac):

$ echo -e 'A\nB\nC' | sed '1!G;h;$!d'
C
B
A
$ echo -e 'A\nB\nC' | sedsed --debug '1!G;h;$!d'
PATT:A$
HOLD:$
COMM:1 !G
PATT:A$
HOLD:$
COMM:h
PATT:A$
HOLD:A$
COMM:$ !d
PATT:B$
HOLD:A$
COMM:1 !G
PATT:B\nA$
HOLD:A$
COMM:h
PATT:B\nA$
HOLD:B\nA$
COMM:$ !d
PATT:C$
HOLD:B\nA$
COMM:1 !G
PATT:C\nB\nA$
HOLD:B\nA$
COMM:h
PATT:C\nB\nA$
HOLD:C\nB\nA$
COMM:$ !d
PATT:C\nB\nA$
HOLD:C\nB\nA$
C
B
A

三、统计

3.1 怎么检查一个文本文件中某一行的长度?

这里n表示行号,p打印出匹配内容(到标准输出),该命令通常与-n命令行选项连用。那么,怎样来获取长度计数呢?很明显,我们需要通过管道输出给wc命令来计算。

# sed –n 'n p' file.txt | wc –c

要得到文本文件第五行的长度,运行如下命令:

 data]# sed -n '5 p' hmslogAD.txt |wc -c
67

四、修改文本

4.1 如何向文本指定位置插入另外一个文本?

有这么一个需求,需要往指定的html中插入新生成的table标签,前面的样式是固定的。GP 以html格式生成的查询结果滤出关键字table然后插入第37行之后,最后邮件发送出来。

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.    <meta charset="UTF-8">
  5.    <h1 align="center"> GP 慢查询</h1>
  6. </head>
  7. <body>
  8. <!-- CSS goes in the document HEAD or added to your external stylesheet -->
  9. <style type="text/css">
  10. table.imagetable {
  11.    font-family: verdana,arial,sans-serif;
  12.    font-size:11px;
  13.    color:#333333;
  14.    border-width: 1px;
  15.    border-color: #999999;
  16.    border-collapse: collapse;
  17. }
  18. table.imagetable th {
  19.    background:#b5cfd2 url('cell-blue.jpg');
  20.    border-width: 1px;
  21.    padding: 8px;
  22.    border-style: solid;
  23.    border-color: #999999;
  24. }
  25. table.imagetable td {
  26.    background:#dcddc0 url('cell-grey.jpg');
  27.    border-width: 1px;
  28.    padding: 8px;
  29.    border-style: solid;
  30.    border-color: #999999;
  31. }
  32. </style>
  33. <!-- Table goes in the document BODY -->
  34. <table class="imagetable">
  35. <tr>
  36.    <th>rank</th><th>content</th>
  37. </tr>

这里填上需要的table数据

</table>

</body>

</html>

这里主要讨论和sed有关的地方,sed -i 可以对文件直接进行操作。

一般使用最多的是sed -i进行 替换。

使用sed 添加一个文件到指定文件指定行。


  • 37行
  • tmp.txt 需要添加在37行之后的文件
  • slowQuery.html 目标文件,对应上面的html文件
sed -i "37 r /home/scripts/slowQuery/tmp.txt" slowQuery.html

结果:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <h1 align="center"> GP 慢查询</h1>
</head>
<body>
<!-- CSS goes in the document HEAD or added to your external stylesheet -->
<style type="text/css">
table.imagetable {
    font-family: verdana,arial,sans-serif;
    font-size:11px;
    color:#333333;
    border-width: 1px;
    border-color: #999999;
    border-collapse: collapse;
}
table.imagetable th {
    background:#b5cfd2 url('cell-blue.jpg');
    border-width: 1px;
    padding: 8px;
    border-style: solid;
    border-color: #999999;
}
table.imagetable td {
    background:#dcddc0 url('cell-grey.jpg');
    border-width: 1px;
    padding: 8px;
    border-style: solid;
    border-color: #999999;
}
</style>
<!-- Table goes in the document BODY -->
<table class="imagetable">
<tr>
    <th>rank</th><th>content</th>
</tr>
<tr valign="top">
    <td align="right">1</td>
    <td align="left">查询提交时间 :2020-10-15 15:42:35.24;当前gp有慢查询:procpid :6829;sess_id :7051266;sql为 :select glass_id, min(substring(glass_id,2,2)) as year, min(substring(glass_id,4,1)) as month  from wpp_fdefect_panel_f where db_timestamp &gt;= '2020-10-15 15:10:00.0' and db_timestamp &lt; '2020-10-15 15:30:00.0' and ope_id = 'CB353' and real_flg = 'Y' and substring(glass_id,1,1) in ('A','C') and glass_id not like '%*%' group by glass_id  order by year, month</td>
  </tr>
</table>
</body>
</html> 

五、统计某行中包含数字的个数

使用wc + sed + 正则实现

]#echo "w9q9e3 12312312"|wc -m
16
]#echo "w9q9e3 12312312"|wc -L
15
]#echo "w9q9e3 12312312"|wc -c
16
#wc -L选项,统计最长行的长度
         -L, --max-line-length
              print the length of the longest line
         -l, --lines
              print the newline counts
   -l用于统计有多少个新行 -L 代表的是某行中最长的长度
        -c, --bytes
              print the byte counts
       -m, --chars
              print the character counts

借助sed 和正则


正则 [^0-9] 代表非数字


模式s  使用替换模式替换


模式g  将模式2粘贴到/pattern n/

]#echo "w9q9e3 12312312"|sed  s'/[^0-9]//'g
99312312312

将非数字替换为空白就得到了如上数字串.


此处要使用wc的-L 参数,  wc的参数如上.

]#echo "w9q9e3 12312312"|sed  s'/[^0-9]//'g|wc -L
11

六、sed 和正则搭配使用

分离数组和字母

输入:


tmp]# cat sed.txt

abc1234567890

abc0987654321

xyz1234567890

输出:


1234567890

0987654321

1234567890


方法一

 tmp]# sed -n 's/^\([a-z]\{3\}\)\([0-9]\{3,\}\)/\2/p' sed.txt
1234567890
0987654321
1234567890
  • ([a-z]{3})  字母匹配三次
  • ([0-9]{3,}) 数字匹配至少三次,最多不限


以上两个正则将文本分为两部分,\2p 打印第二部分匹配到的内容就是我们想要的.


反斜线符号“ \ ”在Bash中被解释为转义字符,用于去除一个单个字符的特殊意义,它保留了跟随在之后的字符的字面值,除了换行符


如果要输出字母:取正则的第二个分组,即\2

]# sed -n 's/^\([a-z]\{3\}\)\([0-9]\{3,\}\)/\1/p' sed.txt
abc
abc
xyz

方法二:引入正则

]# sed -r -n 's/^([a-z]{3})([0-9]{3,})/\2/p' sed.txt
1234567890
0987654321
1234567890

这里有个小坑,就是转义, 如果在括号前加\ 则代表原义括号了


总之一句话,想少用\  那你就用-r

格式化数字串

输入:1234567


输出:123,456,7 或者1,234,567

[root@ninesun example]# echo "1234567" | sed -r 's/([0-9]{3})([0-9]{3})(.*)/\1,\2,\3/'
123,456,7
[root@ninesun example]# 
[root@ninesun example]# echo "1234567" | sed -r 's/(.*)([0-9]{3})([0-9]{3})/\1,\2,\3/'
1,234,567

如果输入的字符串越来越长如何解决?位置引用最多只能用9个括号.


例如123456792378937892498279842,如何分隔?


需要引入分支,使用子模式在大数字中插入逗号


设置一个分支标签LABEL供"b"、"t"命令跳转

'b LABEL'
无条件跳转到标签LABEL上。如果LABEL参数省略,则跳转到SCRIPT的尾部准备进入下一个sed循环,即跳转到隐含动作auto_print的前面。
't LABEL'
如果对最近读入的行有"s"命令的替换成功了,则跳转到LABEL标签处。如果LABEL参数省略,则跳转到SCRIPT的尾部准备进入下一个sed循环,即跳转到隐含动作auto_print的前面。

有以上前置知识后看下面这个例子就好理解了。

[root@ninesun ~]# echo "This, is, a, test, to, remove, commas." | sed -n '{:l; s/,//1p; tl}'
This is, a, test, to, remove, commas.
This is a, test, to, remove, commas.
This is a test, to, remove, commas.
This is a test to, remove, commas.
This is a test to remove, commas.
This is a test to remove commas.
[root@ninesun ~]# 
[root@ninesun ~]# 
[root@ninesun ~]# echo "This, is, a, test, to, remove, commas." | sed -n '{:l; s/,//1p; bl}'
This is, a, test, to, remove, commas.
This is a, test, to, remove, commas.
This is a test, to, remove, commas.
This is a test to, remove, commas.
This is a test to remove, commas.
This is a test to remove commas.
  • :l 定义一个l标签
  • s/,/ /1p 从左往右第一个逗号出现的位置换位空格
  • tl 最后一次替换成功,标签结束(t和l之间的空格可省略)

分支的思想类似于迭代.

084dd4b195b543a4b577212fd80003e2.png

大数字中插入逗号

#方式一: 分多行书写
]# echo "123456792378937892498279842" | sed '{
:start
s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/
t start
}'
123,456,792,378,937,892,498,279,842
#方式二:写在一行
~]# echo "12345672332135490854389679123" | sed -r '{:start; s/(.*[0-9])([0-9]{3})/\1,\2/; t start}'
12,345,672,332,135,490,854,389,679,123

.*[0-9]

[0-9]{3}

这个模式会查找两个子模式。第一个子模式是以数字结尾的任意长度的字符。第二个子模式

是若干组三位数字。如果这个模式在文本中找到了(对应分支lable 中的t),替代文本会在两个子模式之间加一个逗号,每个子模式都会通过其位置来标示。这个脚本使用测试命令来遍历这个数字,直到放置好所有的逗号。

打印序号

[root@ninesun example]# sed '=' passwd
1
root:x:0:0:root:/root:/bin/bash
2
bin:x:1:1:bin:/bin:/sbin/nologin
3
daemon:x:2:2:daemon:/sbin:/sbin/nologin
4
adm:x:3:4:adm:/var/adm:/sbin/nologin
5
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6
sync:x:5:0:sync:/sbin:/bin/sync
7
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8
halt:x:7:0:halt:/sbin:/sbin/halt
9
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10
operator:x:11:0:operator:/root:/sbin/nologin
# N将匹配到的行与下一行合并
[root@ninesun example]# sed '=' passwd | sed -r 'N;s/\n/ /g'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
[root@ninesun example]# 
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin

打印末尾行

sed采用行号计数器即时计数,每读取一行,计数器就加1。因此sed在读取到最后一行前,不知道后面还有多少行,也不知道什么时候才是最后一行。直到读取到输入流的最后一行,sed为该行打上"$"标记,表示这是最后一行。"$"只是一个标记符号,并非行号,行号只在计数器中记录,因此无法通过"$"来计算出倒数几行,例如"$-1"是错误的写法。


例如,要输出倒数10行,这个窗口就一直维持在10行的固定大小。当读取到最后一行时,可以通过"$"符号来判断这是否是最后一行,是的话就输出该窗口,否则不输出该窗口的数据。类似于一个滑动窗口。

chapter21]# sed ':l $q; N; 11,$D; b l' data7.txt

1dd9703955e248a5bbe60e536105403a.png

去掉字符串中的引号

1.  ⚡ root@ninesun ~  echo ""tag_name": "v1.3.1"," | sed -E 's/.*"v([^"]+)".*/\1/'
2. tag_name: v1.3.1,

替换模式将括号中的引用(非引号出现 1次或多次)替换掉


相关实践学习
CentOS 7迁移Anolis OS 7
龙蜥操作系统Anolis OS的体验。Anolis OS 7生态上和依赖管理上保持跟CentOS 7.x兼容,一键式迁移脚本centos2anolis.py。本文为您介绍如何通过AOMS迁移工具实现CentOS 7.x到Anolis OS 7的迁移。
目录
相关文章
|
4月前
|
Linux Perl
在Linux中,如何使用请用 cut 或者 awk,sed命令取出 linux 中 eth0 的 IP 地址?
在Linux中,如何使用请用 cut 或者 awk,sed命令取出 linux 中 eth0 的 IP 地址?
|
3月前
|
机器学习/深度学习 Linux Perl
Linux文本处理三剑客之sed详解
这篇博客详细讲解了Linux中的文本处理工具sed的使用方法和常用命令。
202 9
Linux文本处理三剑客之sed详解
|
3月前
|
Linux Perl
Linux之sed命令
Linux之sed命令
|
3月前
|
人工智能 监控 Shell
常用的 55 个 Linux Shell 脚本(包括基础案例、文件操作、实用工具、图形化、sed、gawk)
这篇文章提供了55个常用的Linux Shell脚本实例,涵盖基础案例、文件操作、实用工具、图形化界面及sed、gawk的使用。
597 2
|
3月前
|
监控 Linux Shell
30 个实用的 Linux 命令贴与技巧,提升你的效率(附实战案例)
本文介绍了30个实用的Linux命令及其应用场景,帮助你提升命令行操作效率。涵盖返回目录、重新执行命令、查看磁盘使用情况、查找文件、进程管理、网络状态监控、定时任务设置等功能,适合各水平的Linux用户学习和参考。
|
3月前
|
Linux Perl
6-20|linux sed命令
6-20|linux sed命令
|
4月前
|
Linux 文件存储 数据安全/隐私保护
Linux用户组管理实战:创建、管理与删除的全面指南
在 Linux 系统中,用户组管理是实现权限控制和资源共享的关键。本文档详细介绍如何创建用户组、管理用户组成员及查看与删除用户组。首先,通过 `groupadd` 命令创建新用户组,并在 `/etc/group` 文件中记录。接着,利用 `usermod` 和 `gpasswd` 命令来添加或删除用户组成员,其中 `gpasswd` 提供更灵活的管理方式。最后,使用 `getent` 或直接读取 `/etc/group` 查看用户组信息,并通过 `groupdel` 删除空用户组。这些操作有助于高效管理和保护系统资源。
326 4
|
4月前
|
Linux Shell Perl
在Linux中,如何使用sed命令进行文本替换?
在Linux中,如何使用sed命令进行文本替换?
|
4月前
|
Linux
Linux源码阅读笔记19-插入删除模块实战
Linux源码阅读笔记19-插入删除模块实战
|
4月前
|
Linux 调度
Linux源码阅读笔记05-进程优先级与调度策略-实战分析
Linux源码阅读笔记05-进程优先级与调度策略-实战分析