我在试着修改一个标记文件。在一个文件中,有许多类似这个的链接。
[string one](/stringtwo/#stringthree)我想将这些修改如下:
[string one](stringtwo.html#stringthree)删除斜杠并添加.html。
我尝试了以下几点:
sed -i 's/](\(\/.*\)#/](\1.html#/g' file但是它返回[global configuration](/config/.html#globals)。它不能去除斜杠。
如何使用bash或sed实现这一点?
发布于 2022-11-18 05:11:32
这似乎起了作用:
$ cat 725364.in
[string one](/stringtwo/#stringthree)
[example label](/path/to/doc/#anchor)
$ sed 's_\(\[[^]]*]\)(/\([^#]*\)/\(#[^)]*\))_\1(\2.html\3)_g' 725364.in
[string one](stringtwo.html#stringthree)
[example label](path/to/doc.html#anchor)要把它分解:
首先,我用s_needle_pin_flags来表示sed而不是s/needle/pin/flags,这样就不必逃避字面意义上的/s了。
sed将使用此表达式\(\[[^]]*]\)(/\([^#]*\)/\(#[^)]*\))搜索,细分为:
\(\[[^]]*]\) -第1组(链接标签)的定义:[]的](/ -字面上的(/\([^#]*\) -第2组的定义(网址):#中的零或多个/ -字面上的/\(#[^)]*\) -第3组(锚)的定义:#)的零或多个) -字面上的)并使用\1(\2.html\3)对其进行转换,细分为:
(,然后是.html,然后是)发布于 2022-11-18 05:02:56
在's/](\(\/.*\)#/](\1.html#/g'中匹配的组D1确实包含斜杠。您应该在组\/之外指定\(\/.*\)。试试这个:
sed -i 's/](\/\(.*\)\/#/](\1.html#/g' file 发布于 2022-11-18 17:21:18
使用Raku (以前称为Perl_6)
~$ raku -pe 's{ \( ~ \) [(\/) ( .+? ) (\/) (\# .+ )] $ } = "($1.html$3)";' 725364.in#或(更正式)
~$ raku -pe 's{ \( ~ \) [(\/) ( <-[#]>+? ) (\/) (\# <-[#]>+ )] $ } = "($1.html$3)";' 725364.in样本输入(感谢@DopeGhoti):
[string one](/stringtwo/#stringthree)
[example label](/path/to/doc/#anchor)样本输出:
[string one](stringtwo.html#stringthree)
[example label](path/to/doc.html#anchor)由于OP希望更改/正斜杠,所以使用了与常规的s/// Raku替换语法不同的语法。Raku还提供了一个s{ … } = " … "替换语法,用于上述(或s[ … ] = " … "等)。
在第一个原子中,Raku的~倾斜语法用于嵌套数据结构。基本上,regex \( ~ \) [ … ]表示“方括号中的组被括号包围”。然后,regex将/正斜杠捕获到$0,非贪婪的字符序列捕获到$1,第二个/正斜线捕获到$2,并捕获由#辛托索普启动到$3的终端贪婪字符序列。
显示捕获(将-pe标志更改为-ne并添加say):
~$ perl6 -ne 'say s{ \( ~ \) [(\/) ( .+? ) (\/) (\# .+ )] $ } = "($1.html$3)";' 725364.in
「(/stringtwo/#stringthree)」
0 => 「/」
1 => 「stringtwo」
2 => 「/」
3 => 「#stringthree」
「(/path/to/doc/#anchor)」
0 => 「/」
1 => 「path/to/doc」
2 => 「/」
3 => 「#anchor」在替换中,还原未捕获的括号。被捕获的/正斜杠被删除.$1中捕获的路径是输出的,然后是.html,然后是$3,它是捕获的#八进制启动的终端字符串。
https://unix.stackexchange.com/questions/725364
复制相似问题