开发者

Run expand on find results

I'm trying to run the expand shell command on all files found by a find command. I've tried -exec and xargs but both failed. Can anyone explain me why? I'm on a mac for the record.


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

This just creates 开发者_开发百科a file {} with all the output instead of overwriting each individual found file itself.


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

And this just outputs

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


Your command does not work for two reasons.

  1. The output redirection is done by the shell and not by find. That means that the shell will redirect finds output into the file {}.
  2. The redirection would occur immediately. That means that the file will be written even before it is read by the expand command. So it's not possible to redirect a command's output into the input file.

Unfortunately expand doesn't allow to write it's output into a file. So you have to use output redirection. If you use bash you could define a function that executes expand, redirects the output into a temporary file and move the temporary file back over the original file. The problem is that find will run a new shell to execute the expand command.

But there is a solution:

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

export -f expand_func

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

You are exporting the function expand_func to sub shells using export -f. And you don't execute expand itself using find -exec but you execute a new bash that executes the exported expand_func.


'expand' isn't really worth the trouble. You can just use sed instead:

find . -name "*.php" | xargs sed -i -e 's/\t/    /g'
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜