【问题标题】:Using sed to retrieve and modify a single line in the file使用 sed 检索和修改文件中的单行
【发布时间】:2014-07-20 08:38:46
【问题描述】:

我有一个 bash 脚本需要注释掉文件中第一个非注释行并显示它,如下所示:

env=$(grep -v -m 1 "#" file)
if [ "$env" != "" ]
then
    sed -i "/\<$env\>/s/^/#/" file
fi
echo $env

变成这样:

#this is an example file
this is the first line
this is the second line

进入这个:

#this is an example file
#this is the first line
this is the second line

并回应这个this is the first line

我相信有一种更直接、更规范的方法可以做到这一点,也许只使用 sed。它是单行的,因为它实际上是通过 ssh 执行的。另一方面,通过 ssh 执行会导致在 sed 参数中扩展环境变量出现问题,并且使用 \\\$env 转义它不起作用。非常感谢任何建议。

【问题讨论】:

    标签: bash replace sed grep comments


    【解决方案1】:

    正如您已经建议的那样,您只能使用sed

    sed '0,/^[^#]/ s/^[^#].*/#\0/' file.txt
    

    上述 sed 命令适用于从文件的第一行到第一个未注释行的范围。在此范围内,它将用# 替换未注释行的开头。因为该范围只适用于第一个未注释的行,所以只有这一行会被注释。

    【讨论】:

    • 没问题。 sed 规则! ;)
    • 是的,但乍一看,它看起来像克林贡语
    【解决方案2】:

    假设你正在使用枪sed

    sed -i '/^[^#]/{s/^/#/;:S;N;bS;}' file
    

    当匹配第一个非注释行时,它将在该行之前添加一个#并读取剩余行。 由于它将读取剩余行到 PatternSpace,如果这是一个大文件并且在第一个非注释行之后有很多行,它将占用大量内存。

    最好的答案是 luis_js,我仍然在这里写我的答案,只是提供一种不同的方式。

    既然OP提到了,我在这里保留我的第一个答案(但它是错误的)

    sed '/^#/{n;s/^/#/;}' file
    

    它会在注释行之后重新添加注释行,并且只有在第一个非注释行之前有奇数注释行时才能注释第一个非注释行。

    【讨论】:

      【解决方案3】:

      如果您找到带有# 的行,则转到下一行。 如果下一行以#开头,则转到下一行,否则添加#

      sed -e '/#/{:start; n; /^#/b start; s/^/#/}; '  file.txt
      

      【讨论】:

        【解决方案4】:

        有一个答案,但它被删除了。出于教育目的,我认为值得一提:

        sed -i '/^#/{n;s/^/#/}' file
        

        这是最短的一段代码,但它消除了 cmets。 (你在文件中得到“##”)。因此,如果其他人在他们的特定场景中不介意这一点,它仍然很有用......

        【讨论】:

        • 这是我的答案,我发现它是错误的。当您的文件首先包含两个注释行时,它将再次注释第二个 cmets,并且对第三行不执行任何操作。它仅在您首先有奇怪的注释行时才有效。
        猜你喜欢
        • 1970-01-01
        • 2014-02-02
        • 1970-01-01
        • 1970-01-01
        • 2015-03-19
        • 1970-01-01
        • 1970-01-01
        • 2011-10-09
        相关资源
        最近更新 更多