【问题标题】:How to insert a line using sed before a pattern and after a line number?如何在模式之前和行号之后使用 sed 插入一行?
【发布时间】:2019-03-29 08:09:27
【问题描述】:

如何在模式之前和行号之后使用sed 在文件中插入一行?以及如何在 shell 脚本中使用它?

这会在带有模式的每一行之前插入一行:

sed '/Sysadmin/i \ Linux Scripting' filename.txt

这使用行号范围改变了这一点:

sed '1,$ s/A/a/'

那么现在如何使用这两者(我不能)在模式之前和行号之后使用sed 将一行插入文件或其他方法?

【问题讨论】:

    标签: shell unix awk sed


    【解决方案1】:

    您可以编写一个 sed 脚本文件并使用:

    sed -f sed.script file1 ...
    

    或者您可以使用(多个)-e 'command' 选项:

    sed -e '/SysAdmin/i\
    Linux Scripting' -e '1,$s/A/a/' file1 ...
    

    如果你想在一行之后附加一些东西,那么:

    sed -e '234a\
    Text to insert after line 234' file1 ...
    

    【讨论】:

    • 乔纳森,如果我有这种格式的xml :: 如何使用 sed 添加一行 "
      我想通了,感谢您的帮助:sed -i -e '8,$ s//testing/' -e '/testing/i\ ' -e '8,$ s/testing//'vendors1.xml
    • 为了让这个工作到位,我必须这样做sed -i '22a Text I Added at Line 22' test.txt
    • @jamescampbell :这意味着您正在使用 GNU sed,也意味着您想要覆盖原始文件。这些不一定是原始要求的一部分。这没有错;只是(稍微)不同。使用 BSD sed,您需要使用 -i ‘’ 而不仅仅是 -i,您将无法在 POSIX 规范上作弊并省略反斜杠换行符。
    • @JonathanLeffler 感谢这是一个很好的解释,现在很有意义。
    【解决方案2】:

    我假设您只想在当前行号大于某个值时才在模式之前插入行(即,如果模式出现在行号之前,则什么也不做)

    如果你没有绑定到sed

    awk -v lineno=$line -v patt="$pattern" -v text="$line_to_insert" '
        NR > lineno && $0 ~ patt {print text}
        {print}
    ' input > output
    

    【讨论】:

    • +1:我想知道这个问题是否也应该这样解释,但给出了更简单的答案,这似乎很有帮助。在sed 中很难实现这种效果 - 可能并非完全不可能,但涉及嵌套命令等。
    【解决方案3】:

    这是一个如何在文件中的一行之前插入一行的示例:

    示例文件 test.txt:

    hello line 1
    hello line 2
    hello line 3
    

    脚本:

    sed -n 'H;${x;s/^\n//;s/hello line 2/hello new line\n&/;p;}' test.txt > test.txt.2
    

    输出文件 test.txt.2

    hello line 1
    hello new line
    hello line 2
    hello line 3
    

    注意!请注意,sed 将换行符替换为没有空格的开头 - 这是必要的,否则生成的文件将在开头有一个空行

    脚本找到包含“hello line 2”的行,然后在上面插入一个新行——“hello new line”

    sed 命令解释:

    sed -n:
    suppress automatic printing of pattern space
    
    H;${x;s/test/next/;p}
    
    /<pattern>/  search for a <pattern>
    ${}  do this 'block' of code
    H    put the pattern match in the hold space
    s/   substitute test for next everywhere in the space
    x    swap the hold with the pattern space
    p    Print the current pattern hold space. 
    

    【讨论】:

      【解决方案4】:

      简单吗?从第 12 行到最后:

      sed '12,$ s/.*Sysadmin.*/Linux Scripting\n&/' filename.txt
      

      【讨论】:

      • 这适用于 GNU sed;它不适用于所有其他变体。我专门用 sed 的 BSD/macOS 变体进行了测试,例如它会生成 Linux ScriptingnSysadmin。我还用 GNU sed 测试了相同的脚本,它工作了——我改变的只是执行命令的路径。
      • @JonathanLeffler 感谢您的解释。我现在记得我“很久以前”在 Solaris 和 AIX 上遇到了换行问题。
      猜你喜欢
      相关资源
      最近更新 更多
      热门标签