我有一个名为test-domain的文件,其内容包含 100.am 行。
当我这样做时,100.am的行将从测试域文件中删除,如预期的那样:
for x in $(echo 100.am); do sed -i "/$x/d" test-domain; done
但是,如果不是 echo 100.am ,我会从名为unwanted-lines的文件中读取每一行,但它不起作用。
for x in $(cat unwanted-lines); do sed -i "/$x/d" test-domain; done
即使不想要的行的唯一内容是一行,并且具有确切的内容 100.am ,这就是这样。
如果您在变量中使用 echo ,有没有人知道为什么sed删除行有效,但如果您使用 cat 则没有?
答案 0 :(得分:5)
fgrep -v -f unwanted-lines test-domain > /tmp/Buffer
mv /tmp/Buffer test-domain
在这种情况下,由于shell中的多次调用(效率低下并且使用了大量的资源),因此sed并不感兴趣。仍然使用sed的方法是预加载要删除的行,并根据这个预加载的信息进行搜索,但在这种情况下与fgrep相比非常重要
答案 1 :(得分:1)
有人知道为什么sed删除行有效,如果你在你的使用回声 变量,但如果你使用猫不是吗?
我认为包含不需要的行的文件包含CR+LF
行结尾,因此在您使用该文件时它不起作用。您可以在循环中删除CR:
for x in $(cat unwanted-lines); do x="${x//$'\r'}"; sed -i "/$x/d" test-domain; done
答案 2 :(得分: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
是标准编辑。
答案 3 :(得分:-1)
为什么不在您的文件上应用sed命令?
sed -i '/.*100\.am/d' your_file