【问题标题】:sed command to print a string after certain patternsed 命令在特定模式后打印字符串
【发布时间】:2020-08-01 17:34:34
【问题描述】:

尝试在如下行/语句之后使用 sed 打印字符串,

class name extends #(p val1 = 10,
                     p val2 = 20,
                     p val3 = 30) f_name;


"class" 和 "extends" 和 ";" 在该行/语句的末尾(即,使用多行)将保持不变,其余项是随机的。

预期结果:

class name extends #(p val1 = 10,
                     p val2 = 20,
                     p val3 = 30) f_name;

string t;

试用如下,

试用命令:

sed -i '/^class/a\\string t;'

试用结果:

class name extends #(p val1 = 10,
string t;
                     p val2 = 20,
                     p val3 = 30) f_name;


如果 class 语句与下面在同一行结束,则上述命令可以正常工作

class name extends f_name;

但在消耗多行时不起作用。

请就此提出建议。

【问题讨论】:

    标签: regex sed


    【解决方案1】:

    必须使用多行技术。使用 GNU sed:

    sed -E '/^\s*class\s+\w+\s+extends\b/{ :a; /;\s*$/!{N; ba}; s/$/\nstring t;/ }' file
    

    【讨论】:

      【解决方案2】:
      perl -lpe '$class=1 if /^class/; if ($class and /;$/) { $_ .= "\nstring t;"; $class = 0 }` file
      

      当看到以class 开头的行时,上面的命令会记住。然后添加一行string t; 并忘记看到class,当它看到一行以; 结尾时。

      请参阅https://perldoc.perl.org/perlrun.html 以获取有关使用的各种选项的帮助。

      【讨论】:

      • 感谢您的回复。 perl -lpe '$class=1 if /^class/; if ($class and /;$/) { $_ .= "\nstring t;"; $class= 0 }' 文件--------> 这行得通。但无法在文件中更新更改。使用-i,仍然可以工作。给出错误“无法打开 perl 脚本 :: 未找到此类文件或目录”
      • perl -i -lpe'$class=1 if /^class/; if ($class and /;$/) { $_ .= "\nstring t;"; $class= 0 }' 文件。这行得通。
      【解决方案3】:

      Ed 可以做到这一点。

      #!/bin/sh
      
      cat >> append.ed << EOF
      \$
      a
      
      string t;
      .
      wq
      EOF
      
      ed -s filename < append.ed
      rm -v ./append.ed
      

      【讨论】:

      • 我认为你没有抓住重点。 OP 正在尝试在输入文件中出现不同的多行字符串后打印字符串,而不仅仅是尝试将字符串添加到文件的末尾 - 您可以使用 printf '\nstring t\n' &gt;&gt; filename 来做到这一点。
      【解决方案4】:

      使用 GNU sed 表示 -z(将整个输入作为单个字符串读取)和 \n 表示替换文本中的换行符:

      $ sed -z 's/class name extends[^;]*;/&\n\nstring t;/' file
      class name extends #(p val1 = 10,
                           p val2 = 20,
                           p val3 = 30) f_name;
      
      string t;
      

      否则在每个 UNIX 机器上的任何 shell 中使用任何 awk:

      $ awk '
          { r = (NR>1 ? r ORS : "") $0 }
          END { sub(/class name extends[^;]*;/,"&\n\nstring t;",r); print r }
      ' file
      class name extends #(p val1 = 10,
                           p val2 = 20,
                           p val3 = 30) f_name;
      
      string t;
      

      【讨论】:

        【解决方案5】:

        这个 perl 单行代码可以完成这项工作:

        perl -0777 -ape 's/\bclass \w+ extends[\s\S]+?;\K/\nstring t;/' file
        class name extends #(p val1 = 10,
                             p val2 = 20,
                             p val3 = 30) f_name;
        string t;
        

        说明:

        s/                # substitute
            \b              # word boundary
            class           # literally
            \w+             # 1 or more word characters (class name)
            extends         # literally
            [\s\S]+?        # 1 or more any character including newline
            ;               # semi colon
            \K              # forget all we have seen until this position
        /                 # with
            \n              # linefeed
            string t;       # literally
        /                 # end subs
        

        【讨论】:

        • 在 perl 脚本内部使用时如何使用这个 perl 单行器?我收到错误。 system ( "perl -i -lpe '$class=1 if /^class/; if ($class and /;$/) { $_ .= "\n string t\;"; $class= 0 }' $file_path" );
        • system(q(perl -0777 -ape 's/\bclass \w+ extends[\s\S]+?;\K/\nstring t;/' 文件));在 perl 脚本中使用时,这不起作用并给出错误
        • @Hancy:不要使用system(.....)。在您的 Perl 脚本中,打开文件(slurp 模式)然后执行替换并写入修改后的数据。
        【解决方案6】:

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

        sed '/^class/!b;:a;/;$/!{N;ba};/extends/astring t;' file
        

        如果当前行没有开始class,不感兴趣。

        如果当前行没有结束;,则追加下一行并重复。

        如果当前行包含extended,则追加另一行string t;


        如果是空行,则需要包含string t; 的行,或者:

        sed '/^class/!b;:a;/;$/!{N;ba};/extends/G;//astring t;' file
        

        或:

        sed '/^class/!b;:a;/;$/!{N;ba};/extends/a\\nstring t;' file
        

        【讨论】:

          猜你喜欢
          • 2017-07-19
          • 1970-01-01
          • 2019-11-08
          • 2014-12-03
          • 2021-01-14
          • 2017-01-16
          • 1970-01-01
          • 1970-01-01
          • 2021-10-28
          相关资源
          最近更新 更多