【问题标题】:Add a block of text after another with sed使用 sed 一个接一个地添加一个文本块
【发布时间】:2015-02-10 07:07:58
【问题描述】:

我想添加以下文本块 //这里还有更多文字 区域“mysite.com”{ 类型大师; 文件“mysite.com.fwd”; 允许更新{无; }; };

就在下面显示的文本块之后

zone "." IN {
    type hint;
    file "named.ca";
};

文件最终应如下所示

 //There are more lines up here
 zone "." IN {
        type hint;
        file "named.ca";
    };

  zone "mysite.com" {
       type master;
       file "mysite.com.fwd";
         allow-update { none; };
         };
            //There are more lines below here

这里的困难在于要匹配的模式中的 \n 不适用于 sed。

感谢您在高级方面的帮助

【问题讨论】:

标签: regex linux bash sed


【解决方案1】:

我会这样做:

sed "/^};/a \ \nzone \"mysite.com\" {\n type master;\n file \"mysite.com.fwd\";\n allow-update { none; };\n};\n" test.conf

之前

zone "." IN {
 type hint;
 file "named.ca";
};

之后

zone "." IN {
 type hint;
 file "named.ca";
};

zone "mysite.com" {
 type master;
 file "mysite.com.fwd";
 allow-update { none; };
};

^}; 是此处的模式,之后您可以使用a 附加新块,如果需要,您可以更改模式。

另一种更灵活的 sed 方法 - 使用文件,其中有新块:

sed "/^};/r block.conf" test.conf

这里我们只是使用读取命令r 将文本从block.conf 添加到test.conf/^};/ 又是你的模式。

我猜这个范围模式应该是唯一的/file \"named.ca\";/,/^};/,所以这应该很适合你

sed "/file \"named.ca\";/,/^};/ {
/file*/n
a \ \nzone \"mysite.com\" {\n type master;\n file \"mysite.com.fwd\";\n allow-update { none; };\n};\n
}
" test.conf

//,// 结构表示从具有适当模式的行开始并以另一个结束的范围模式。在我们的例子中,它是 2 行模式,我们想跳过第一行,这里是 /file*/n。然后我们将块添加到从空行开始的第二行的 and 处。

这里也有一些有用的方法:How to sed a block of text with specific pattern?

【讨论】:

  • 它实际上是相反的,zone "." IN 是之前文件中的内容,zone "mysite.com" 是需要添加的内容。请编辑您的答案。谢谢
  • zone "." IN之前有文字(所以不是文件的开头。抱歉造成误解
  • 如果你有更多这样的文字 };你只需要使用另一种模式。并且您的新块将附加在模式之后。但是你必须想出独特的模式。
【解决方案2】:

sed 不是一个好的工具。在 shell 中做这件事很简单:

cat file1 >> file2

表示将file1中的内容追加到file2的末尾。

更新:

sed -e '$r file1' file2 > file2

会起作用的。

仍然不明白为什么 sed 比 shell 更安全。

【讨论】:

  • 问题是你加块后有几行
  • @user2650277 为什么不添加更多cat?或之后使用sed?有什么限制?
  • 它是一个配置文件(named.conf),我不能破坏东西。sed 在这种情况下是最安全的
  • 我们还没有到达文件末尾,zone "mysite.com" 区域下方还有更多文字,zone "." IN 之前还有更多文字。
  • @HuStmpHrrr 如您所见,OP 说我想在特定块之后添加文本块,而他在该块之后还有另一行。请参阅他发布的输出的最后一行//There are more lines below here,并且在提到的第一行中的块之前还有一行//There are more lines up here
【解决方案3】:

如果您想要一个合适且强大的解决方案,有一些 的模块可以解析 bind8 配置文件。

查看Unix::Conf::Bind8::Conf

【讨论】:

    【解决方案4】:

    假设以下代码在“my_file”中,并用“^”代替换行符以获得一大行。我们现在可以匹配模式"file "named.ca";,然后在此之后替换新代码。然后将“^”转换回换行符“\n”。

    cat 'my_file'|tr '\n' '^'|sed 's#//There are more lines up here- zone.*\(file "named.ca"\).*#\1  zone "mysite.com" {\n        type master;\n        file "mysite.com.fwd";\n            allow-update { none; }; };\n#g'|tr '^' '\n'
    

    结果

    //There are more lines up here
     zone "." IN {
            type hint;
            file "named.ca";
        };
    
      zone "mysite.com" {
           type master;
           file "mysite.com.fwd";
             allow-update { none; };
             };
                //There are more lines below here
    

    【讨论】:

      【解决方案5】:

      我无法让其中任何一个在 MacOS 上运行。

      这对我有用:

      sed -i '' "/^\s*};/ a \\
      \\
      \zone "mysite.com" {\\
      \  type master;\\
      \  file "mysite.com.fwd";\\
      \  allow-update { none; };\\
      \};\\
      " filename
      

      这是使用以下脚本进行测试的。它创建一个新文件,打印出来,修改它并再次打印:

      testfile="testsed.txt"
      rm ${testfile}
      cat <<EOF > ${testfile}
      //There are more lines up here
      zone "." IN {
        type hint;
        file "named.ca";
      };
      EOF
      cat ${testfile}
      
      sed -i '' "/^\s*};/ a \\
      \\
      \zone "mysite.com" {\\
      \  type master;\\
      \  file "mysite.com.fwd";\\
      \  allow-update { none; };\\
      \};\\
      " ${testfile}
      
      echo
      echo "==== After Transform ===="
      echo
      cat ${testfile}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-29
        • 1970-01-01
        • 2020-11-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多