【问题标题】:shell scripts how to replace string between 2 characters in all lines start with specific string?shell脚本如何替换所有行中2个字符之间的字符串以特定字符串开头?
【发布时间】:2012-11-05 20:26:12
【问题描述】:

我有一个如下所示的文本文件,我想用新字符串替换两个字符之间的旧字符串(在这种情况下是 ^|)(在这种情况下将替换为旧字符串 ^旧字符串)如果该行以特定字符串开头(在此示例中为MMX

文本文件原件:

General start, this is a test file.
TAG okay, this line not need to be processed.
MMX ABCD ^string1|other strings abc
CCF ABCD ^string2|other strings cde, skip line
MMX CDEE ^String3|other strings aaa
MMX AAAA ^String4|other strings bbb
CCD BBBB ^String5|other strings ccc, skip line

修改后的文本文件应该是:

General start, this is a test file.
TAG okay, this line not need to be processed.
MMX ABCD ^string1^String1|other strings abc
CCF ABCD ^string2|other strings cde, skip line
MMX CDEE ^String3^String3|other strings aaa
MMX AAAA ^String4^String4|other strings bbb
CCD BBBB ^String5|other strings ccc, skip line

如何使用 shell 脚本来执行这项工作?

【问题讨论】:

    标签: shell unix scripting sed awk


    【解决方案1】:

    这是使用sed的一种方式:

    sed '/^MMX/s/\(\^[^|]*\)/\1\1/' file.txt
    

    结果:

    General start, this is a test file.
    TAG okay, this line not need to be processed.
    MMX ABCD ^string1^string1|other strings abc
    CCF ABCD ^string2|other strings cde, skip line
    MMX CDEE ^String3^String3|other strings aaa
    MMX AAAA ^String4^String4|other strings bbb
    CCD BBBB ^String5|other strings ccc, skip line
    

    【讨论】:

    • @user1831356:如果此解决方案或此处的任何其他解决方案对您有用,您应该考虑通过单击您最喜欢的答案左侧的接受勾来接受它。谢谢!
    【解决方案2】:

    只是为了完整性:

    $ awk '/^MMX/{sub(/\^[^|]+/,"&&")}1' file
    General start, this is a test file.
    TAG okay, this line not need to be processed.
    MMX ABCD ^string1^string1|other strings abc
    CCF ABCD ^string2|other strings cde, skip line
    MMX CDEE ^String3^String3|other strings aaa
    MMX AAAA ^String4^String4|other strings bbb
    CCD BBBB ^String5|other strings ccc, skip line
    

    但我会使用已发布的 sed 解决方案之一,因为这是单行的简单替换,这是 sed 擅长的。

    【讨论】:

      【解决方案3】:

      您可以为sed 提供一个“地址”,它是执行命令的行的过滤器:

      sed '/^MMX/s/\^(.*)\|/^\1^\1|/g'
      

      在这种情况下,地址为/^MMX/,命令为s///g,并将\^(.*)\|替换为^\1^\1|,其中\1是括号中的部分。

      【讨论】:

        【解决方案4】:
        perl -plne "if(/^MMX/){$_=~s/([^\^]*)([^\|]*)(.*)/$1$2$2$3/g;}" your_file
        

        测试如下:

        >perl -plne "if(/^MMX/){$_=~s/([^\^]*)([^\|]*)(.*)/$1$2$2$3/g;}" new.txt
        General start, this is a test file.
        TAG okay, this line not need to be processed.
        MMX ABCD ^string1^string1|other strings abc
        CCF ABCD ^string2|other strings cde, skip line
        MMX CDEE ^String3^String3|other strings aaa
        MMX AAAA ^String4^String4|other strings bbb
        CCD BBBB ^String5|other strings ccc, skip line
        

        【讨论】:

          【解决方案5】:

          要确保新字符串中的大写:

          sed '/^MMX/s/\^\([^|]\+\)/^\1^\u\1/'
          

          【讨论】:

          • \u 之类的快捷方式仅限于 GNU sed。作为一般规则,出于便携性考虑,应避免使用它们。
          【解决方案6】:

          sed s/^MMX([^^])^([^|])\|(.+)/MMX\1^\2^\2\|\3/ 文件名

          【讨论】:

          • 不工作,给出这个信息:sed: -e expression #1, char 38: invalid reference \3 on `s' command's RHS
          • 转到 vi 并在命令模式下执行 :1,$s/^MMX([^^]*)^([^|]*)\|(.+)/MMX\1^ \2^\2\|\3/
          猜你喜欢
          • 1970-01-01
          • 2013-05-03
          • 1970-01-01
          • 1970-01-01
          • 2018-07-08
          • 2021-06-20
          • 2020-04-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多