在Unix中,从sed重定向到文件会导致文件清空。

时间:2017-11-09 09:45:05

标签: bash unix redirect sed

我试图将“unix”(忽略大小写)的所有实例替换为“oracle”。所以,我捕获“testfile2”和管道,在sed之后我重定向回相同的文件“testfile2”。但是文件变空了。有人可以帮助调试。

bash-3.2$ cat testfile2
uniX
udfi
unix
UNix
UNIX
Unix
ockcl
cunci

bash-3.2$ cat testfile2 |tr [A-Z] [a-z] |sed 's/unix/oracle/g' > testfile2
bash-3.2$ cat testfile2
bash-3.2$

我能够使用tee得到一个解决方法如下,但无法理解为什么重定向不起作用。

bash-3.2$ cat testfile2 |tr [A-Z] [a-z] |sed 's/unix/oracle/g' |tee  testfile2
oracle
udfi
oracle
oracle
oracle
oracle
ockcl
cunci

bash-3.2$ cat testfile2
oracle
udfi
oracle
oracle
oracle
oracle
ockcl
cunci

我正在使用bash版本3.2.57(1)-release(solaris2.10)

1 个答案:

答案 0 :(得分:2)

cat testfile2 |tr [A-Z] [a-z] |sed 's/unix/oracle/g' > testfile2

当shell看到> testfile2时,它会将文件截断为零字节 - 这是在其他任何事情之前完成的。在sed"之后没有完成#34;但在它之前!你将重定向放在右边的事实是无关紧要的(大多数人这样做,但实际上你几乎可以把它放在任何地方)。

重定向到其他文件名(例如testfile2.tmp),然后在命令成功运行后使用mv重命名。

编辑:

正如@tripleee指出的那样,[A-Z] [a-z]是错误的。 tr不使用正则表达式或glob结构(通配符),方括号表示转换方括号(如果它们在引号内)。

但它们不在引号内,所以[A-Z] [a-z]将由 shell 解释,并将替换为文件名。但是,只有在当前目录中有单个字符文件名时才会发生这种情况 - 不太可能,但可能。 tr 'A-Z' 'a-z'是正确的。