1

我有一个名为 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 也是如此

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

4

4 回答 4

5
fgrep -v -f unwanted-lines test-domain > /tmp/Buffer
mv /tmp/Buffer test-domain

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

于 2013-11-11T13:15:51.393 回答
1

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

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

for x in $(cat unwanted-lines); do x="${x//$'\r'}"; sed -i "/$x/d" test-domain; done
于 2013-11-11T13:18:11.620 回答
1

一种比你更好的策略是使用真正的编辑器,例如 ,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是标准编辑器。

于 2013-11-11T13:20:22.410 回答
-1

为什么不直接在你的文件上应用 sed 命令呢?

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

于 2013-11-11T13:16:35.407 回答