我有一个如下所示的文件:
some
arbitrary number of
leading
lines
a prefix followed by wmd v0.0.0-20220406135915-ce5e3ee6c6bf
some
trailing
lines
这只是文件外观的一个示例。对于我感兴趣的产品线,不变的部分是:
- 总有
wmd v0.0.0-
, 其次是 - 14 位数字,后面跟着
- 连字符,后跟
- 12 个字母数字字符
如何编写一个sed
命令,允许我用20220406135915-ce5e3ee6c6bf
shell 变量中的值替换该部分new_text
?
换句话说,如果new_text
有值99999999999999-aaaaaaaaaaaa
,我想找到将产生以下输出的命令<whatever goes here>
部分:sed
$ sed -e "s/wmd v0.0.0-<whatever goes here>/wmd v0.0.0-$new_text/" my-file.txt
some
arbitrary number of
leading
lines
a prefix followed by wmd v0.0.0-99999999999999-aaaaaaaaaaaa
some
trailing
lines
答案1
您可以使用\{..\}
量词来指定字符类应匹配的次数。
sed -e "s/wmd v0\.0\.0-[0-9]\{14\}-[0-9a-f]\{12\}/wmd v0.0.0-$new_text/"
# ~ ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~
另请注意,点在正则表达式中具有特殊含义。反斜杠使其字面匹配。
另请注意,如果$new_text
包含斜杠或 sed 特有的其他一些字符,该命令可能会中断。
答案2
使用乐(以前称为 Perl_6)
~$ raku -pe 's/ "wmd v0.0.0-" <( \d**14 \- \w**12 )> /99999999999999-aaaaaaaaaaaa/' my-file.txt
#OR
~$ raku -pe 's[ "wmd v0.0.0-" <( \d**14 \- \w**12 )> ] = "99999999999999-aaaaaaaaaaaa";' my-file.txt
输入示例:
some
arbitrary number of
leading
lines
a prefix followed by wmd v0.0.0-20220406135915-ce5e3ee6c6bf
some
trailing
lines
示例输出:
some
arbitrary number of
leading
lines
a prefix followed by wmd v0.0.0-99999999999999-aaaaaaaaaaaa
some
trailing
lines
上面的正则表达式使用 4 个正则表达式原子来识别匹配项 , "wmd v0.0.0-"
, \d**14
,\-
和\w**12
。当然,如果你对引号有问题,"wmd v0.0.0-"
可以这样写wmd \s v0 \. 0 \. 0 \-
(即所有非alnum
字符都被反斜杠转义)。
捕获标记<( … )>
用于删除 之外的所有内容\d**14 \- \w**12
,并在运算符的右半部分替换s///
。
注意,上面的代码中\w
是 的简写<alnum>
,其中包含_
下划线。如果您不想接受_
下划线(实际上,可能是 12 个连续的_
下划线字符),请使用类似的内容<[0..9a..z]>**12
。
最后,您可以通过将替换抽象为变量来简化替换,如下所示:
~$ raku -pe 'my $new = "99999999999999-aaaaaaaaaaaa"; \
s/ "wmd v0.0.0-" <( \d**14 \- <[0..9a..z]>**12 )> /$new/;' my-file.txt
https://raku.org