【问题标题】:change a line with awk用 awk 换行
【发布时间】:2021-12-02 11:36:18
【问题描述】:

例如,我试图用 awk 替换文件中的一行

改变这个:

e1 is (on)

e2 is (off)

到:

e1 is (on)

e2 is (on)

使用命令:

awk '/e2/{gsub(/off/, "on")};{print}' ~/Documents/Prueba > ~/Documents/Prueba

这会进行替换,但文件以空白结尾!

【问题讨论】:

    标签: bash awk


    【解决方案1】:

    另一个答案,使用不同的工具(sed 和 -i(就地)标志)

    sed -i '/e2/ s/off/on/' ~/Documents/Prueba
    

    【讨论】:

    【解决方案2】:

    您的 awk 是正确的,但是您正在重定向到与原始文件相同的文件。这导致原始文件在被读取之前被覆盖。您需要将输出重定向到不同的文件。

    awk '/e2/{gsub(/off/, "on")};{print}' ~/Documents/Prueba > ~/Documents/Prueba.new
    

    如有必要,之后重命名 Prueba.new。

    【讨论】:

    • +1。强调“原始文件[被]覆盖之前它已被读取”
    【解决方案3】:

    正如其他答案和问题“Why reading and writing the same file through I/O redirection results in an empty file in Unix?”中所解释的那样,shell 重定向会在您的输入文件被读取之前破坏它。

    要在不显式使用临时文件的情况下解决该问题,请查看moreutils 集合中的sponge 命令。

    awk '/e2/{gsub(/off/, "on")};{print}' ~/Documents/Prueba | sponge ~/Documents/Prueba
    

    或者,如果您的系统上安装了 GNU awk,您可以使用 in place extension

    gawk -i inplace '/e2/{gsub(/off/, "on")};{print}' ~/Documents/Prueba
    

    【讨论】:

      【解决方案4】:

      你也可以先用cat读取文件,然后用pipe重定向到stdout,再用awk从stdin读取:

      cat ~/Documents/Prueba | awk '/e2/{gsub(/off/, "on")};{print}' - > ~/Documents/Prueba
      

      我相信破折号- 是可选的,因为您只是在阅读标准输入。

      一些有趣的文档:https://www.gnu.org/software/gawk/manual/html_node/Naming-Standard-Input.html

      【讨论】:

        【解决方案5】:

        您不能将输出重定向到与输入文件相同的文件。选择另一个文件名。

        > 将首先清空您的文件。


        你可以试试sponge

        【讨论】:

          猜你喜欢
          • 2016-10-29
          • 2014-08-25
          • 2017-07-09
          • 2022-06-28
          • 2014-10-05
          • 1970-01-01
          • 2011-01-23
          • 2012-04-13
          • 2011-01-02
          相关资源
          最近更新 更多