2012-11-26 53 views
3

我试图操纵从find命令的文件名:终端find命令:操纵输出字符串

find . -name "*.xib" -exec echo '{}' ';' 

例如,这可能会打印:

./Views/Help/VCHelp。厦门国际银行

我想使它:

./Views/Help/VCHelp.strings

我试了一下:

find . -name "*.xib" -exec echo ${'{}'%.*} ';' 

但 '{}' 不能被识别为一个字符串或东西...


我也试过如下:

find . -name "*.xib" -exec filename='{}' ";" -exec echo ${filename%.*} ";" 

但它是试图执行一个名为“文件名”,而不是分配变量命令:

发现:文件名:没有这样的文件或目录

+1

我编辑了答案,解释了为什么你不能简单地使用'-exec filename ='{}'“;”',请确保你阅读了它。 – livibetter

回答

5

不能使用参数扩展与字面串。尝试将它先存储在一个变量:

find . -name '*.xib' -exec bash -c "f='{}' ; echo \${f%.xib}.strings" \; 

-exec看到的第一个参数之后的命令,因此不能简单地把它filename='{}'因为find不使用sh执行你给出什么。如果你想运行一些shell的东西,你需要使用shbash来包装。

或者使用sed

find . -name '*.xib' | sed 's/.xlib$/.strings/' 
+0

完美,我想明白为什么我的试验失败了。谢谢。 – Mazyod

+0

当然,如果一个文件名包含单引号,你的第一个方法就会失败。 –

+0

另外,尝试'触摸$'lol.xib \ nnotfunny.xib',看看会发生什么......这两种方法都失败了。我希望这不会用在生产脚本中。 –

1
find . -name "*.xib" | sed -e 's/\.xib$/.strings/' 
2

对于这样一个简单的搜索,你可以使用纯bash的解决方案:

#!/bin/bash 

shopt -s globstar 
shopt -s nullglob 

found=(**.xib) 

for f in "${found[@]}"; do 
    echo "${f%xib}strings" 
done 

开启globstar外壳选项上使**为“匹配所有文件和零个或多个目录和子目录“(引自bash参考手册)。如果没有匹配,nullglob选项会有所帮助:在这种情况下,glob将展开为空,而不是丑陋的**.xib。该解决方案对于包含有趣角色的文件名是安全的。