5

我正在尝试对命令找到的所有文件运行扩展 shellfind命令。我试过 -exec 和 xargs 但都失败了。谁能解释我为什么?我在Mac上记录。


find . -name "*.php" -exec expand -t 4 {} > {} \;

这只是创建一个{}包含所有输出的文件,而不是覆盖每个找到的文件本身。


find . -name "*.php" -print0 | xargs -0 -I expand -t 4 {} > {}

这只是输出

4 {}
xargs: 4: No such file or directory
4

2 回答 2

10

您的命令不起作用有两个原因。

  1. 输出重定向由 shell 完成,而不是find. 这意味着 shell 会将finds 的输出重定向到文件{}中。
  2. 重定向将立即发生。这意味着文件将在命令读取之前被写入expand。所以不可能将命令的输出重定向到输入文件中。

不幸expand的是,不允许将其输出写入文件。所以你必须使用输出重定向。如果您使用bash,您可以定义一个function执行expand,将输出重定向到一个临时文件并将临时文件移回原始文件。问题是find它将运行一个新的shell来执行expand命令。

但是有一个解决方案:

expand_func () {
  expand -t 4 "$1" > "$1.tmp"
  mv "$1.tmp" "$1"
}

export -f expand_func

find . -name \*.php -exec bash -c 'expand_func {}' \;

您正在expand_func使用 . 将函数导出到子 shell export -f。而且您不会expand使用执行自身,而是执行执行导出find -exec的新的。bashexpand_func

于 2011-07-13T17:53:46.480 回答
1

'expand' 真的不值得麻烦。您可以只使用 sed 代替:

find . -name "*.php" | xargs sed -i -e 's/\t/    /g'
于 2013-09-09T15:25:21.833 回答