在路径中查找+ cp空格,并且需要重命名。如何?

时间:2019-01-15 21:49:41

标签: bash

我需要递归地找到所有名为“ config.xml”的文件,并将它们放在一旁进行分析。路径中留有空格,只是为了使其有趣。但是,我需要它们是唯一的,否则它们将在同一文件夹中发生冲突。我想做的基本上是复制它们,但是使用找到它们的目录的名称。我想要的命令类似于this question中的命令,除了我需要执行$(dirname {})之类的命令之外。当我这样做时,什么都不会移动(但我没有错误)

示例但不起作用的命令: find . -name 'config.xml' -exec sh -c 'cp "$1" "$2.xml"' -- {} "$HOME/data/$(dirname {})" \;

3 个答案:

答案 0 :(得分:2)

您可以这样使用它:

find . -name 'config.xml' -exec bash -c \
'd="$HOME/data/${1%/*}/"; mkdir -p "$d"; command cp -p "$1" "$d"' - {} \;

答案 1 :(得分:2)

仅用一个外壳即可执行此操作,而找不到每个文件一个外壳(如先前的答案所使用):

while IFS= read -r -d '' filename; do 
  outFile="$HOME/data/${filename%/*}.xml"
  mkdir -p -- "${outFile%/*}"
  cp -- "$filename" "$outFile"
done < <(find . -name 'config.xml' -print0)

通过这种方式,您的find发出NUL分隔的文件名流,并由父shell中的while read循环逐一使用。

(您可以使用"$HOME/data/$(dirname "$filename").xml",但是从性能角度来看,这确实很愚蠢:$() fork()位于子外壳之外,而dirname是一个外部可执行文件,需要exec进行链接和加载;仅当您可以在shell本身内部进行字符串操作时,这些开销都没有指向)。

答案 2 :(得分:1)

-exec sh有点难处理,但并非不可能。 $(dirname ...)在运行sh之前被展开,因此等于dirname {}-文件{}的目录名。做类似-exec sh -c ' .... ' -- {}的操作,然后使用$(dirname ... )$1放入sh脚本中。

find . -name 'config.xml' -exec sh -c 'cp "$1" "$2/data/$(dirname "$1").xml"' -- {} "$HOME" \;