$ cat example.txt
产量:
example
test
example
我想从此文件中删除“test”字符串。
$ grep -v test example.txt > example.txt
$ cat example.txt
$
下面的方法可行,但我感觉有更好的方法!
$ grep -v test example.txt > example.txt.tmp;mv example.txt.tmp example.txt
$ cat example.txt
example
example
值得注意的是,这将位于一个超过 10,000 行的文件中。
干杯
你可以使用 sed,
sed -i '/test/d' example.txt
-i
保存对该文件所做的更改。所以你不需要使用重定向运算符。
-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if SUFFIX supplied)
你的做法是正确的,但在 mv 之前使用
&&
以确保 grep 成功,否则你将删除原始文件:
grep -F -v test example.txt > example.txt.tmp && mv example.txt.tmp example.txt
我还添加了
-F
选项,因为您说要删除字符串,而不是正则表达式。
您可以使用
sed -i
但是您需要担心找出和/或转义 sed 分隔符,并且 sed 不支持搜索字符串,因此您需要尝试转义搜索字符串中正则表达式字符的所有可能组合尝试让 sed 将它们视为文字字符(由于正则表达式字符的位置敏感性质,您无法自动化这一过程),它所节省的只是手动命名您的 tmp 文件,因为 sed 无论如何在内部使用一个文件。
哦,另一种选择 - 您可以使用带有“就地编辑”功能的 GNU awk 4.*。它也像 sed 一样在内部使用 tmp 文件,但它确实支持字符串操作,因此您不需要尝试转义 RE 元字符,并且它没有分隔符作为语法的一部分而需要担心:
awk -i inplace -v rmv="test" '!index($0,rmv)' example.txt
任何 grep/sed/awk 解决方案都会在眨眼间运行 10,000 行文件。
您的
grep
命令将立即导致输出文件 (example.txt
) 打开以进行写入。这会删除(“截断”)文件的内容,因此文件在开始读取时为空。
moreutils
包中的
sponge
命令专为此类情况而设计,例如
grep -v test example.txt | sponge example.txt
这是有效的,因为sponge
将缓冲其所有输入,并且仅在完成接收输入后才打开给定文件(
example.txt
)进行写入。请注意,对于大于 RAM 的文件来说,这可能不是一个好主意!