【发布时间】:2009-12-13 09:17:57
【问题描述】:
如果我将命令的输出重定向到它读取的同一文件,则其内容将被删除。
sed 's/abd/def/g' a.txt > a.txt
谁能解释一下原因?
【问题讨论】:
标签: shell unix io-redirection
如果我将命令的输出重定向到它读取的同一文件,则其内容将被删除。
sed 's/abd/def/g' a.txt > a.txt
谁能解释一下原因?
【问题讨论】:
标签: shell unix io-redirection
重定向所做的第一件事是打开文件进行写入,从而清除所有现有内容。 sed 然后尝试读取您刚刚创建的这个空文件,并且什么也不做。然后关闭文件,不包含任何内容。
【讨论】:
重定向操作<、>等由shell处理。当您向 shell 发出包含重定向的命令时,shell 将首先打开该文件。在> 的情况下,文件将被打开以进行写入,这意味着它被截断为零大小。打开重定向文件后,shell 启动一个新进程,将其标准输入、输出和错误绑定到任何可能的重定向文件,然后才执行您提供的命令。因此,当您的示例中的 sed 命令开始执行时,a.txt 已被 shell 截断。
顺便说一句,这也是您不能直接对sudo 使用重定向的原因,因为需要权限才能打开重定向文件的是shell,而不是正在执行的命令。
【讨论】:
您需要使用-i 选项来编辑文件:
sed -i .bck 's/abd/def/g' a.txt
编辑:正如尼尔所说,重定向首先打开文件进行写入,从而清除它。
EDIT2:对某些读者来说可能会很有趣
在 OSX 上,如果您想使用带有空扩展名的 -i 来防止创建备份文件,您还需要使用 -eswitch 否则无法正确解析参数:
sed -i -e 's/abc/def/g' a.txt
【讨论】:
stdout 和 stderr 将首先准备好,然后是 stdin,然后执行命令。所以 a.txt 首先对于标准输出是明确的,然后当命令执行时找不到任何内容。 尝试 sed -i 's/abd/def/g' a.txt 或者 sed 's/abd/def/g' a.txt 1 a.txt
【讨论】: