【问题标题】:Unexpected behavior of find -execfind -exec 的意外行为
【发布时间】:2016-10-22 18:28:42
【问题描述】:

我发现“find -exec” bash 命令的行为出乎我的意料,我将不胜感激。同样的工作可以用“for file_name in find ....; do....”循环来完成,所以问题是为什么它不适用于 find 的 -exec 选项。

有两个文件夹(SRC/ 和 src/)包含相同的文件集。我想比较这些文件夹中的文件:

find src/ -type f -exec sh -c "diff {} `echo {} | sed 's/src/SRC/'`" \;

但是,这不会比较文件...由于某种原因 sed 命令不会进行替换。如果每个文件夹中只有一个文件,例如“a”,那么一个命令

find src/ -type f -exec sh -c "echo {} `echo {} | sed 's/src/SRC/'`" \;

输出

src/a src/a

如果在 bash 中做类似的事情,以下所有命令都会给出相同的结果 (SRC/a):

echo src/a | sed 's/src/SRC/'
echo `echo src/a | sed 's/src/SRC/'`
sh -c "echo src/a | sed 's/src/SRC/'"
sh -c "echo `echo src/a | sed 's/src/SRC/'`"

但如果将此命令提供给“find -exec ...”,则输出会有所不同:

find src/ -type f -exec bash -c "echo {} | sed 's/src/SRC/'" \;

给出“SRC/a”

find src/ -type f -exec bash -c "echo `echo {} | sed 's/src/SRC/'`" \;

给出“src/a”

这是预期的行为吗?

【问题讨论】:

  • 你为什么不用diff -r SRC src
  • 转义 `\`
  • @Michael 这是一个很好的观点,但它没有回答我的问题。回答你的问题:最初我想在最后得到一些唤起 emacs -q --eval '(ediff-merge-files "file2" "file2")' 的东西,但意识到 find 有问题......然后简化为这个例子......
  • 如果 shell 命令太长,那么更好的选择是函数。

标签: bash sed find


【解决方案1】:

sh -c 使用单引号,因为脚本首先由您的shell 解释。并将文件名作为sh 的参数传递,而不是在引号内使用{}

find src/ -type f -exec sh -c 'diff "$1" "$(printf "%s\n" "$1" | sed "s/src/SRC/")"' _ {} \;

或者使用 bash:

find src/ -type f -exec bash -c 'diff "$1" "${1/src/SRC}"' _ {} \; 

【讨论】:

  • 我喜欢第二种方法+1
  • 在这种非常特殊的情况下,您实际上并不需要 Bash:find src/ -type f -exec sh -c 'diff "$1" "SRC${1#src}"' _ {} \;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-13
  • 2014-07-27
相关资源
最近更新 更多