使用 sed 将双下划线的完全匹配替换为字符串
replace an exact match for a double underscore with a string using sed
我正在尝试用字符串替换双下划线的精确匹配。
sed -i 's/\<__\>/.abc.def__/g' file
但这会使文件保持不变。感谢任何指点。
从 Sed match exact
跟进
如果您没有重叠匹配项(并且您提供的输入有 none),像这样的 sed
可以:
sed -E 's/([^_]|^)__([^_]|$)/.abc.def__/g' file > newfile
此处,([^_]|^)__([^_]|$)
匹配并捕获到第 1 组 (</code>) 中除 <code>_
或字符串开头 (([^_]|^)
) 之外的任何字符,然后匹配 __
,然后将 _
以外的任何字符或字符串结尾 (([^_]|$)
).
捕获到第 2 组 (</code>)
<p>如果可以有重叠匹配,<code>sed
在这里就变得相当难用了。一个完美的替代方法是使用
perl -pe 's/(?<!_)__(?!_)/.abc.def__/g' file > newfile
perl -i -pe 's/(?<!_)__(?!_)/.abc.def__/g' file
(?<!_)__(?!_)
正则表达式包含两个环视,(?<!_)
否定后视,确保当前位置左侧没有 _
字符,(?!_)
负先行确保当前位置右侧没有 _
个字符。
#!/bin/bash
s='AFM_7499_190512_110136_001_p_EQ4H_1_s60_0012__386___Day_'
sed -E 's/([^_]|^)__([^_]|$)/.abc.def__/g' <<< "$s"
# => AFM_7499_190512_110136_001_p_EQ4H_1_s60_0012.abc.def__386___Day_
perl -i -pe 's/(?<!_)__(?!_)/.abc.def__/g' <<< "$s"
# => AFM_7499_190512_110136_001_p_EQ4H_1_s60_0012.abc.def__386___Day_
这可能对你有用 (GNU sed):
sed -E 's/^/\n/;:a;ta;s/\n__($|[^_])/.abc.def__\n/;ta;s/\n(_+|[^_]+)/\n/;ta;s/\n//' file
在当前行前添加一个换行符。
通过使用换行符作为分隔符的行进行模式匹配。
如果模式匹配,替换为所需的字符串并将分隔符放在替换上。
否则,沿线移动分隔符并重复。
在行尾,删除引入的换行符。
选择:
sed -E 's/(^|[^_])__($|[^_])/\n/g;s//\n/g;s/\n/.abc.def__/g' file
我正在尝试用字符串替换双下划线的精确匹配。
sed -i 's/\<__\>/.abc.def__/g' file
但这会使文件保持不变。感谢任何指点。 从 Sed match exact
跟进如果您没有重叠匹配项(并且您提供的输入有 none),像这样的 sed
可以:
sed -E 's/([^_]|^)__([^_]|$)/.abc.def__/g' file > newfile
此处,([^_]|^)__([^_]|$)
匹配并捕获到第 1 组 (</code>) 中除 <code>_
或字符串开头 (([^_]|^)
) 之外的任何字符,然后匹配 __
,然后将 _
以外的任何字符或字符串结尾 (([^_]|$)
).
</code>)
<p>如果可以有重叠匹配,<code>sed
在这里就变得相当难用了。一个完美的替代方法是使用
perl -pe 's/(?<!_)__(?!_)/.abc.def__/g' file > newfile
perl -i -pe 's/(?<!_)__(?!_)/.abc.def__/g' file
(?<!_)__(?!_)
正则表达式包含两个环视,(?<!_)
否定后视,确保当前位置左侧没有 _
字符,(?!_)
负先行确保当前位置右侧没有 _
个字符。
#!/bin/bash
s='AFM_7499_190512_110136_001_p_EQ4H_1_s60_0012__386___Day_'
sed -E 's/([^_]|^)__([^_]|$)/.abc.def__/g' <<< "$s"
# => AFM_7499_190512_110136_001_p_EQ4H_1_s60_0012.abc.def__386___Day_
perl -i -pe 's/(?<!_)__(?!_)/.abc.def__/g' <<< "$s"
# => AFM_7499_190512_110136_001_p_EQ4H_1_s60_0012.abc.def__386___Day_
这可能对你有用 (GNU sed):
sed -E 's/^/\n/;:a;ta;s/\n__($|[^_])/.abc.def__\n/;ta;s/\n(_+|[^_]+)/\n/;ta;s/\n//' file
在当前行前添加一个换行符。
通过使用换行符作为分隔符的行进行模式匹配。
如果模式匹配,替换为所需的字符串并将分隔符放在替换上。
否则,沿线移动分隔符并重复。
在行尾,删除引入的换行符。
选择:
sed -E 's/(^|[^_])__($|[^_])/\n/g;s//\n/g;s/\n/.abc.def__/g' file