Lin*_*oob 5 sed wildcards files
我正在使用 GNU sed 4.2.2,搜索后无法找出sed在某些情况下行为异常的原因:
我有一个包含以下内容的目录:
foofile.txt
barfile.txt
bazfile.txt
config/
Run Code Online (Sandbox Code Playgroud)
sed -i 's/foo/bar/g' *.txt
Run Code Online (Sandbox Code Playgroud)
这按我的预期工作。它将三个常规文件中的所有“foo”替换为“bar”。
sed -i 's/foo/bar/g' *
sed: couldn't edit config: not a regular file
Run Code Online (Sandbox Code Playgroud)
它在barfile.txtand中用“bar”替换了“foo” bazfile.txt,但在 中不替换foofile.txt。我假设它遍历从*字母顺序扩展的文件列表,当它遇到config/错误并退出时。有没有办法sed忽略错误并继续处理文件?
for file in $(find . -maxdepth 1 -type f); do sed -i 's/foo/bar/g' <"$file"; done
sed: no input files
sed: no input files
sed: no input files
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么sed会这样吗?为什么在给它一个时说没有输入文件?
我知道我可以使用以下内容,但我问的是为什么 sed 会这样,而不是我如何解决这个用例。
find . -maxdepth 1 -type f -exec sed -i 's/foo/bar/g' {} \;
Run Code Online (Sandbox Code Playgroud)
这是正常行为。在这两种情况下都sed以error code 4... per退出info sed:
4
An I/O error, or a serious processing error during runtime,
GNU 'sed' aborted immediately.
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,消息都是不言自明的。不知道什么不清楚,但为了记录:第一次出错是因为它无法编辑目录,第二次它抱怨因为它无法stdin就地编辑,它需要一个文件(即删除之前的重定向$file)
正确的方法以做到这一点find,正如你提到的,通过-exec ...
用水珠,你必须使用一个循环和测试,如果输入是运行前一个普通文件sed。或者,如果您是zsh用户,您可以简单地执行以下操作:
sed -i 's/foo/bar/g' *(.)
Run Code Online (Sandbox Code Playgroud)
案例2:
使用以下命令避免该目录find:
sed -i 's/foo/bar/g' $(find . -maxdepth 1 -type f)
Run Code Online (Sandbox Code Playgroud)
案例3:
问题在于<"$file"循环中,它将文件转换为流,因此sed永远看不到文件名。只需删除它<:
for file in $(find . -maxdepth 1 -type f); do
sed -i 's/foo/bar/g' "$file"
done
Run Code Online (Sandbox Code Playgroud)