$ cat test.txt
foo
bar
此 sed 命令将 text.txt 的第一行替换为“baz”。它在命令行中运行良好:
$ sed "1s%.*%baz%" "test.txt" > "test.txt"
$ cat test.txt
baz
bar
我希望能够将该 sed 命令放入名为test.sh
如下内容的脚本中:
#!/bin/sh
sed "1s%.*%baz%" "test.txt" > "test.txt"
但是,当我运行它时./test.sh
,它会删除 text.txt 中的所有行(text.txt 被完全清空)?!
有任何想法吗?
答案1
您无法(安全地)将命令的输出重定向到它正在读取的文件。您很幸运,它恰好可以从命令行运行。可能在一种情况下,sed
在 shell 破坏它之前能够读取整个文件,而在另一种情况下则不能。这种差异可能是由于某些缓冲问题造成的,但这并不值得弄清楚。
如果您想就地修改文件,您应该将输出写入临时文件,然后(如果成功)将临时文件重命名为输入文件的名称。
例如:
sed "1s%.*%baz%" test.txt > $$ && mv $$ test.txt
$$
是当前 shell 的进程 ID;这是获取合理唯一文件名的便捷方式。或者,即使您没有同名文件test.txt.$$
,也可以使用 或。tmp
在命令的特定情况下sed
,您可以使用-i
选项就地修改文件 - 但这只会导致sed
在内部创建一个临时文件。语法,甚至-i
选项的存在,可能会因实现的不同而不同sed
;请查看您的本地文档。