【问题标题】:replace an exact match for a double underscore with a string using sed使用 sed 将双下划线的完全匹配替换为字符串
【发布时间】:2022-01-03 13:17:00
【问题描述】:

我正在尝试用字符串替换双下划线的完全匹配。

sed -i 's/\<__\>/.abc.def__/g' file

但这会使文件保持不变。感谢任何指针。 跟进Sed match exact

【问题讨论】:

  • \&lt;\&gt; 是单词边界,_ 是单词字符。删除它们。
  • @WiktorStribiżew 但如果我也有三个下划线,我会插入字符串。我如何只匹配__?
  • 您能提供一个示例字符串吗?使用 sed 执行此操作的主要问题是匹配结果出现在结果中(__ 未被删除)。我会在这里使用perlperl -i -pe 's/(?&lt;!_)__(?!_)/.abc.def__/g' file
  • @WiktorStribiżew AFM_7499_190512_110136_001_p_EQ4H_1_s60_0012__386___Day_
  • 我仍然认为 Perl 更好,但sed -E 's/([^_]|^)__([^_]|$)/\1.abc.def__\2/g' file 也可以工作,如果你没有重叠匹配。见ideone.com/9SBMW9

标签: sed


【解决方案1】:

这可能对你有用(GNU sed):

sed -E 's/^/\n/;:a;ta;s/\n__($|[^_])/.abc.def__\1\n/;ta;s/\n(_+|[^_]+)/\1\n/;ta;s/\n//' file

在当前行前添加一个换行符。

模式匹配通过使用换行符作为分隔符的行。

如果模式匹配,则替换为所需的字符串,并将分隔符置于替换上。

否则,沿线移动分隔符并重复。

在行尾,删除引入的换行符。


替代方案:

sed -E 's/(^|[^_])__($|[^_])/\1\n\2/g;s//\1\n\2/g;s/\n/.abc.def__/g' file

【讨论】:

    【解决方案2】:

    如果您没有重叠匹配项(并且您提供的输入没有),则可以使用这样的 sed

    sed -E  's/([^_]|^)__([^_]|$)/\1.abc.def__\2/g' file > newfile
    

    这里,([^_]|^)__([^_]|$) 匹配并捕获除_ 或字符串开头 (([^_]|^)) 之外的任何字符并捕获到第 1 组 (\1),然后匹配 __,然后捕获到第 2 组 (@ 987654329@) 除 _ 或字符串结尾 (([^_]|$)) 以外的任何字符。

    如果可能有重叠的匹配,sed 在这里使用变得相当困难。一个完美的选择是使用

    perl -pe 's/(?<!_)__(?!_)/.abc.def__/g' file > newfile
    perl -i -pe 's/(?<!_)__(?!_)/.abc.def__/g' file
    

    (?&lt;!_)__(?!_) 正则表达式包含两个lookarounds,(?&lt;!_)negative lookbehind 确保当前位置左侧没有_ char,(?!_)negative lookahead 确保没有_ char 紧邻当前位置的右侧。

    the online demo:

    #!/bin/bash
    s='AFM_7499_190512_110136_001_p_EQ4H_1_s60_0012__386___Day_'
    
    sed -E  's/([^_]|^)__([^_]|$)/\1.abc.def__\2/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_
    

    【讨论】:

      猜你喜欢
      • 2021-09-26
      • 1970-01-01
      • 1970-01-01
      • 2018-05-20
      • 1970-01-01
      • 2017-03-20
      • 1970-01-01
      • 2020-01-11
      • 1970-01-01
      相关资源
      最近更新 更多