【问题标题】:sed delete not working with cat variablesed delete 不适用于 cat 变量
【发布时间】:2026-01-10 16:45:01
【问题描述】:

我有一个名为 test-domain 的文件,其内容包含 100.am 行。

当我这样做时,100.am 的行会从测试域文件中删除,正如预期的那样:

for x in $(echo 100.am); do sed -i "/$x/d" test-domain; done

但是,如果我不是 echo 100.am,而是从名为不需要的行的文件中读取每一行,则它不起作用。

for x in $(cat unwanted-lines); do sed -i "/$x/d" test-domain; done

即使不需要的行的唯一内容是一行,其内容也是准确的 100.am

如果您在变量中使用 echo,有谁知道为什么 sed delete 行有效,但如果您使用 cat 则无效?

【问题讨论】:

    标签: bash sed


    【解决方案1】:
    fgrep -v -f unwanted-lines test-domain > /tmp/Buffer
    mv /tmp/Buffer test-domain
    

    sed 在这种情况下并不有趣,因为在 shell 中多次调用(效率低下并且使用了很多资源)。仍然使用 sed 的方法是预加载要删除的行,并根据此预加载的信息进行搜索,但在这种情况下与 fgrep 相比非常重

    【讨论】:

    • 非常感谢,正如您所说,它工作得非常出色,而且看起来比在这里使用 sed 更高效、更整洁。唯一的事情是,我需要先在不需要的 urls 文件上运行 dos2unix。执行 fgrep 比 sed 快得多。
    【解决方案2】:

    如果你在你的 变量,但如果你使用 cat 则不是?

    我相信您的文件包含 不需要的行 包含 CR+LF 行尾,因此在您使用该文件时它不起作用。您可以在循环中剥离 CR:

    for x in $(cat unwanted-lines); do x="${x//$'\r'}"; sed -i "/$x/d" test-domain; done
    

    【讨论】:

    • for x in $(cat ...) 很糟糕,尤其是如果文件unwanted-lines 中有*!然后,您将受到 bash 的干扰。非常非常混乱。此外,这仅适用于每行一个单词的文件。
    • 将答案更改为 - 实际问题是回车(我从 Windows 复制了一个文件)。所以像这样的剥离工作,但也适用于 x in $(cat Wanted-urls | dos2unix);做 sed -i "\~$x~d" 测试域;完成工作。
    【解决方案3】:

    比您更好的策略是使用真正的编辑器,例如ed,如下所示:

    ed -s test-domain < <(
        shopt -s extglob
        while IFS= read -r l; do
            [[ $l = *([[:space:]]) ]] && continue
            l=${l//./\\.}
            echo "g/$l/d"
        done < unwanted-lines
        echo "wq"
    )
    

    警告。您必须确保文件unwanted-lines 不包含任何可能与ed 的正则表达式和命令发生冲突的字符。我已经包含了一段时间的匹配项(即将. 替换为\.)。

    这种方法非常有效,因为您不会在sed 上进行多次分叉、编写临时文件、重命名它们等。

    另一种可能性是使用grep,但是您将没有编辑选项ed提供。

    备注。ed 是标准编辑器。

    【讨论】:

    • 谢谢你,非常有趣的一个!我现在将使用 fgrep 来解决我的特定问题。
    【解决方案4】:

    为什么不对文件应用 sed 命令?

    sed -i '/.*100\.am/d' your_file

    【讨论】:

    • 根本没有解决问题。
    最近更新 更多