请教一个匹配问题

sh/bash/dash/ksh/zsh等Shell脚本
回复
ps3wifi
帖子: 94
注册时间: 2010-01-08 13:09

请教一个匹配问题

#1

帖子 ps3wifi » 2020-03-29 21:08

文本有如下内容
123
232
313
321
用:%s/\(.*\)/(\1)/g这个表达式能搞懂,.*匹配任意字符0到多个,也就是每行内容都能匹配到,(\1)就是前面匹配的内容调用出来分别加上括号
(123)
(232)
(313)
(321)
后面在网上有案例是用:%s/\(.*\)2.*/(\1)/g表达式变成如下内容
(1)
(23)
313
(3)
这个2.*单独出来知道是什么意思,关键变成\(.*\)2.*怎么会是这样输出结果,不知道这个意思,麻烦各位大佬指点解释一下,感谢感谢 :Haha
头像
astolia
论坛版主
帖子: 6503
注册时间: 2008-09-18 13:11

Re: 请教一个匹配问题

#2

帖子 astolia » 2020-03-29 23:55

\(.*\)2.*对于
123:\(.*\)匹配到1,2匹配到2,.*匹配到3,将1加上括号就成了(1)
232:\(.*\)贪婪匹配到23,2匹配到2,.*匹配到空文本,将23加上括号就成了(23)
313:\(.*\)2.*无法匹配,不进行替换
321:同123
ps3wifi
帖子: 94
注册时间: 2010-01-08 13:09

Re: 请教一个匹配问题

#3

帖子 ps3wifi » 2020-03-30 7:46

astolia 写了: 2020-03-29 23:55 \(.*\)2.*对于
123:\(.*\)匹配到1,2匹配到2,.*匹配到3,将1加上括号就成了(1)
232:\(.*\)贪婪匹配到23,2匹配到2,.*匹配到空文本,将23加上括号就成了(23)
313:\(.*\)2.*无法匹配,不进行替换
321:同123
谢谢大佬!解释的太清楚了,相当于\(.*\)这个后面跟的2是单独又匹配一次,不受前面.*贪婪模式影响,另外有一个sed问题patt和hold,真的太烧脑了
1!G是不把hold空间中的缓存内容追加到第一行,h把patt内容复制并覆盖hold中的内容,为什么p打印的时候会变成patt1 hold1 patt2 hold1,这个patt2的内容怎么显示出来了,sed还没有开始处理第二行内容,那个跟在后面的\n在网上找了半天也没有搜索到答案,求大佬再指点一下,感谢万分
cat a7.txt
1
2
3
4
5
6
7
8
9
./sedsed.py -d '1!G;h;$p;' a7.txt
PATT:1$
HOLD:$
COMM:1 !G
PATT:1$
HOLD:$
COMM:h
PATT:1$
HOLD:1$
COMM:$ p
PATT:1$
HOLD:1$
PATT:2$
HOLD:1$
COMM:1 !G
PATT:2\n1$
HOLD:1$
COMM:h
PATT:2\n1$
HOLD:2\n1$
COMM:$ p
PATT:2\n1$
HOLD:2\n1$
PATT:3$
HOLD:2\n1$
COMM:1 !G
PATT:3\n2\n1$
HOLD:2\n1$
COMM:h
PATT:3\n2\n1$
HOLD:3\n2\n1$
COMM:$ p
PATT:3\n2\n1$
HOLD:3\n2\n1$
头像
astolia
论坛版主
帖子: 6503
注册时间: 2008-09-18 13:11

Re: 请教一个匹配问题

#4

帖子 astolia » 2020-03-30 12:25

你对sed的命令格式理解有误
ps3wifi 写了: 2020-03-30 7:46 1!G是不把hold空间中的缓存内容追加到第一行
这条命令的准确意思是:执行G操作,只要当前不是第一行
ps3wifi 写了: 2020-03-30 7:46为什么p打印的时候会变成patt1 hold1 patt2 hold1
$p命令的意思是:如果当前是最后一行,那么执行p操作。所以前面的输出都不是p操作的结果
ps3wifi 写了: 2020-03-30 7:46 这个patt2的内容怎么显示出来了
如果不带-n/--quiet/--silent参数,sed会自动输出每一行的pattern空间。也就是说sed "" a7.txt的效果和cat a7.txt是一样的
带上-n参数,sed -n '1!G;h;$p'就是逆序输出的做法了
ps3wifi 写了: 2020-03-30 7:46 那个跟在后面的\n在网上找了半天也没有搜索到答案
\n就是a7.txt每一行后面的换行符

个人看法是没必要去学sed的hold和标签相关的语法。用awk来处理是一样的,类C语法还更容易理解一些
ps3wifi
帖子: 94
注册时间: 2010-01-08 13:09

Re: 请教一个匹配问题

#5

帖子 ps3wifi » 2020-03-30 19:14

astolia 写了: 2020-03-30 12:25 你对sed的命令格式理解有误
ps3wifi 写了: 2020-03-30 7:46 1!G是不把hold空间中的缓存内容追加到第一行
这条命令的准确意思是:执行G操作,只要当前不是第一行
ps3wifi 写了: 2020-03-30 7:46为什么p打印的时候会变成patt1 hold1 patt2 hold1
$p命令的意思是:如果当前是最后一行,那么执行p操作。所以前面的输出都不是p操作的结果
ps3wifi 写了: 2020-03-30 7:46 这个patt2的内容怎么显示出来了
如果不带-n/--quiet/--silent参数,sed会自动输出每一行的pattern空间。也就是说sed "" a7.txt的效果和cat a7.txt是一样的
带上-n参数,sed -n '1!G;h;$p'就是逆序输出的做法了
ps3wifi 写了: 2020-03-30 7:46 那个跟在后面的\n在网上找了半天也没有搜索到答案
\n就是a7.txt每一行后面的换行符

个人看法是没必要去学sed的hold和标签相关的语法。用awk来处理是一样的,类C语法还更容易理解一些
谢谢大佬解答,令我茅塞顿开,学习awk有没有推荐的书籍,网上找的一些资料也只是片面教材不是很详细的讲解。
头像
astolia
论坛版主
帖子: 6503
注册时间: 2008-09-18 13:11

Re: 请教一个匹配问题

#6

帖子 astolia » 2020-03-30 20:01

回复