【问题标题】:How do I remove all lines matching a pattern from a set of files?如何从一组文件中删除与模式匹配的所有行?
【发布时间】:2012-04-18 09:14:43
【问题描述】:

我有一个令人讨厌的闭源工具,它将特定信息写入其配置文件。如果您随后尝试在其他文件上使用配置,则会加载旧文件。呜呜呜……

幸运的是,配置文件是文本,所以我可以对它们进行版本控制,事实证明,如果只是从文件中删除有问题的行,并没有造成任何伤害。

但该工具不断将这些行放回原处。因此,每次我想签入新版本的配置文件时,我都必须删除所有包含符号 openDirFile 的行。

我即将构建某种 bash 命令来对每个文件运行 grep -v,将结果存储在临时文件中,然后删除原始文件并重命名临时文件,但我想知道是否有人知道一个不错的干净的解决方案,或者已经编写和调试了类似的调用。

为了额外的功劳,如何在不破坏同一目录 (favourite.rc->signals.rc) 中的符号链接的情况下做到这一点?

【问题讨论】:

    标签: bash sed grep pattern-matching


    【解决方案1】:
    sed -i '/openDirFile/d' *.conf
    

    这会删除所有 conf 文件

    如果您的 conf 文件位于不同的路径中,您还可以将该行与“find”命令结合使用。

    请注意,-i 将“就地”删除。

    【讨论】:

    • 如果您是从副本中来到这里的,请注意,如果您的搜索模式在 shell 变量中,则不能使用单引号;在这种情况下,请在您的 sed 脚本周围使用双引号(如果需要,显然要进行调整,即加倍任何文字反斜杠,转义任何文字美元符号等)。 sed -i "/$variable/d" *.conf
    • -i 选项是非标准的,但可以广泛使用。但是,某些平台(包括*BSD / MacOS)要求您为-i指定一个参数,因此sed -i '' 's/openDirFile/d' *.conf
    【解决方案2】:

    这是我想出的 bash 咒语:

    for i in *.rc ; do
        TMP=$(mktemp)
        grep -v openDirFile "$i" >"$TMP" && mv "$TMP" "$i"
    done
    

    (您显然可以通过用分号替换换行符将其变成单行,do 之后除外。)

    肯特的答案显然更胜一筹。

    【讨论】:

      最近更新 更多