直截了当:这不只是匹配数字。
文档中的许多**
散布在 上,我需要用1
和2
替换它们。
**Lorem ipsum dolor **sit amet, consectetur adipisicing elit. **
Ad velit delectus ** quidem itaque eum **accusamus reprehenderit**
illo culpa **** praesentium** ea fugit ****hic in vel officiis,
expedita sit **** et harum enim quaerat, **** ab corporis quo
atque perspiciatis. Minima odit obcaecati** ** reiciendis, sed
rerum ** labore. In fuga, ** aspernatur earum aliquid ** ******
**commodi delectus?
1Lorem ipsum dolor 2sit amet, consectetur adipisicing elit. 1
Ad velit delectus 2 quidem itaque eum 1accusamus reprehenderit2
illo culpa 12 praesentium1 ea fugit 21hic in vel officiis,
expedita sit 21 et harum enim quaerat, 21 ab corporis quo
atque perspiciatis. Minima odit obcaecati2 1 reiciendis, sed
rerum 2 labore. In fuga, 1 aspernatur earum aliquid 2 121
2commodi delectus?
我唯一想到的是执行一个循环,该循环替换找到的第一个匹配项(s/\*{2}/1/
),然后替换第二个匹配项(s/\*{2}/2/
),冲洗并重复,但是由于我仍然不这样做不知道如何将其转换为shellscript,我想知道这是否可以通过使用几个管道sed
命令来实现。
答案 0 :(得分:1)
给出:
$ cat file
**Lorem ipsum dolor **sit amet, consectetur adipisicing elit. **
Ad velit delectus ** quidem itaque eum **accusamus reprehenderit**
illo culpa **** praesentium** ea fugit ****hic in vel officiis,
expedita sit **** et harum enim quaerat, **** ab corporis quo
atque perspiciatis. Minima odit obcaecati** ** reiciendis, sed
rerum ** labore. In fuga, ** aspernatur earum aliquid ** ******
**commodi delectus?
您最好的选择是perl
或awk
:
$ perl -lpE 's/\*\*/$cnt++%2+1/ge' file
这使用perl的能力来评估带有替换的表达式。
方法:
$cnt++
以获得(0,1,2,3,...)
中的每个替换得到的s/\*\*/$cnt++%2+1/ge
; %2
以获得(0,1,0,1,0...)
,然后添加1
以获得(1,2,1,2...)
。 通过相同的方法,可以将awk
与while
循环一起使用:
$ awk '{while (sub(/\*\*/,cnt++%2+1))}1' file
或者,您可以 整个文件(使用-0777
),然后对**[stuff between maybe on multiline]**
进行全局替换,并替换为1[stuff between maybe on multiline]2
:
$ perl -0777 -lnE '$s=$_; $s=~s/\*\*([\s\S]*?)\*\*/1${1}2/g;
END{$s=~s/\*\*/1/; say $s;}' file
请注意最后的$s=~s/\*\*/1/;
,以防替换总数奇数。
所有三种情况下,打印:
1Lorem ipsum dolor 2sit amet, consectetur adipisicing elit. 1
Ad velit delectus 2 quidem itaque eum 1accusamus reprehenderit2
illo culpa 12 praesentium1 ea fugit 21hic in vel officiis,
expedita sit 21 et harum enim quaerat, 21 ab corporis quo
atque perspiciatis. Minima odit obcaecati2 1 reiciendis, sed
rerum 2 labore. In fuga, 1 aspernatur earum aliquid 2 121
2commodi delectus?
答案 1 :(得分:1)
tr '\n' $'\x1' |
sed 's/\*\*/\x2/g' |
sed 's/\x2\([^\x2]*\)\x2/1\12/g; s/\x02/1/' |
tr $'\x1' '\n'
tr
用换行符代替等于十六进制数字0x01
的不可读字符。sed
用两个**
代替十六进制0x02
。0x02<anything>0x02
替换为1<anything>2
\x02
被1
替换。0x01
换行。tutorialspoint的实时版本。
用*
代替0x02
是因为,我们无法沿sed 's/**\(^**\)**/...
做一些事情,即。贪婪地匹配一个字符串,直到找到多字符模式(或者我不知道该怎么做)。因此,我只用一个不可更改的字符替换两个字符**
并处理它。这样,我可以像*
一样正确处理单个**Lor*em ip*sum**
。
如果您的GNU sed具有-z
选项,则不需要替换换行符。
答案 2 :(得分:0)
这可能对您有用(GNU sed):
sed -zE 's/(\*\*)([^*]*(\*[^*]+)*)\1/1\22/g' file
将文件拖入内存。匹配**...**
,并在整个文件中全局将**
前面的**
和1后面的pod 'SwiftDate', '4.5.0'
替换为2。
答案 3 :(得分:0)
使用GNU awk进行多字符RS和RT:
$ awk -v RS='[*][*]' '{ORS=(RT ? (ORS%2+1) : "")}1' file
1Lorem ipsum dolor 2sit amet, consectetur adipisicing elit. 1
Ad velit delectus 2 quidem itaque eum 1accusamus reprehenderit2
illo culpa 12 praesentium1 ea fugit 21hic in vel officiis,
expedita sit 21 et harum enim quaerat, 21 ab corporis quo
atque perspiciatis. Minima odit obcaecati2 1 reiciendis, sed
rerum 2 labore. In fuga, 1 aspernatur earum aliquid 2 121
2commodi delectus?