有时候会我们需要在find命令的-exec选项后面使用多次"{}" 来引用找到的结果。
但是由于cat 命令使用了重定向符号和2次大括号({}),所以,如果不使用 -exec sh -c'cat {} > {}.out.iso' \; 这样的格式的话,find命令肯定会报错的。同时请注意单引号。
于是找了很久,参考了国外一篇文章(http://superuser.com/questions/231495/how-can-i-use-to-redirect-the-output-of-a-command-run-through-finds-exec),改写得到了如下命令,实现了我们的目的。这样使用find命令就方便和更强大了。
find -name "*" -exec sh -c 'cat {} > {}.out.iso' \;
运行此命令之前 :
.:
logo poweranim product_info
./logo:
logo.bmp
./poweranim:
bootanimation.zip shutdownanim.zip shutdownsound startupsound
./product_info:
languages.mk snd_version_info.mk snd_version.xml
运行此命令之后:
$ ls -R
.:
logo logo.out.iso poweranim poweranim.out.iso product_info product_info.out.iso
./logo:
logo.bmp logo.bmp.out.iso
./poweranim:
bootanimation.zip shutdownanim.zip shutdownsound startupsound
bootanimation.zip.out.iso shutdownanim.zip.out.iso shutdownsound.out.iso startupsound.out.iso
./product_info:
languages.mk snd_version_info.mk snd_version.xml
languages.mk.out.iso snd_version_info.mk.out.iso snd_version.xml.out.iso
我们可以删除.out.iso 文件,看看执行这个命令之前是什么样的目录结构。我们先删除cat出来的这些文件:
find -name "*.out.iso" -exec rm {} \;
然后再看看原来的目录结构:
$ ls -R
.:
logo poweranim product_info
./logo:
logo.bmp
./poweranim:
bootanimation.zip shutdownanim.zip shutdownsound startupsound
./product_info:
languages.mk snd_version_info.mk snd_version.xml
其实此功能还有第二种方式的实现(以下为参考):
先写一个简单的脚本 (/tmp/dump.sh):
#!/bin/sh
svn admin dump "$1" > "$1".svn
then:
find /var/svn/* \( ! -name dir -prune \) -type d -exec sh /tmp/dump.sh '{}' \;
通过 -exec sh 执行这个脚本,并把{}所代表的find查找到的内容传入。
对应本文的例子,命令应如下:
find -name "*" -exec sh /tmp/dump.sh '{}' \;
dump.sh 这个脚本的内容如下:
#!/bin/sh
cat "$1" > "$1".out.iso
特别注意:
在find中使用shell命令,其解释器是由 -exec 后面的参数决定的。比如下面的命令,因为cplink.sh脚本中使用了ubuntu默认shell(sh代表默认shell,/bin/sh 链接到了dash),而dash是不支持bash的某些写法的。
find -name "*" -type l -exec bash cplink.sh '{}' '../outxx' \;
cplink.sh 内容如下:
#!/bin/bash
path1=`echo ${1:2}`
path2="$2"/"$path1"
alldir=`dirname $path2`
if [ ! -d $alldir ];then
mkdir -p "$alldir"
fi
##cp link to new dir
cp -d "$1" "$path2"
cplink.sh脚本中的黄色背景中的字段“${1:2}” 是dash所不支持的。
如果使用默认shell (sh/dash),那就会报如下错误:
cplink.sh: 2: Bad substitution
cplink.sh: 2: Bad substitution
cplink.sh: 2: Bad substitution
cplink.sh: 2: Bad substitution
cplink.sh: 2: Bad substitution