反击不起作用

时间:2012-04-09 23:41:48

标签: bash backticks

我想要重命名的目录结构中有大量文件。

文件名采用以下格式:
" AAAAAA-bbbbbb_cccccc-ddddd_eeeee-FFFFF-GGGGG-hhhhh.psd"

我想要这种格式:
" AAAAAA-Bbbbbb_Cccccc-Ddddd_Eeeee-FFFFF-GGGGG-Hhhhh.psd

单个find和sed例程应该将它们转换为正确的格式:

find . -name "*psd" -exec sh -c "echo 'cp '{} `echo {} | sed 's/\([_-][a-z]\)\([A-Z]*\)/\2\U\1/g'`" \;

但它不起作用:

输入:

Assisted-or-Auto / Abstract-Render / assisted-or-auto_abstract-render_tiny-bubbles3.psd

输出:

cp ./Assisted-or-Auto/Abstract-Render/assisted-or-auto_abstract-render_tiny-bubbles3.psd ./Assisted-or-Auto/Abstract-Render/assisted-or-auto_abstract-render_tiny-bubbles3.psd

如果我删除反引号并插入分号,则sed例程有效。

find . -name "*bubbles3.psd" -exec sh -c "echo 'cp '{} ; echo {} | sed 's/\([_-][a-z]\([A-Z]*\)/\2\U\1/g'" \;

cp ./Assisted-or-Auto/Abstract-Render/assisted-or-auto_abstract-render_tiny-bubbles3.psd
./Assisted-Or-Auto/Abstract-Render/assisted-Or-Auto_Abstract-Render_Tiny-Bubbles3.psd

所以,出于某种原因,反击不是应该做的事情。关于如何解决这个问题的任何想法? fyi用"替换反引号$(cmd)"符号具有相同的效果

由于

5 个答案:

答案 0 :(得分:2)

最有可能的是,shell首先解释反引号内的命令(甚至在运行find之前)。但是,“{}”在 find运行之后才会有任何特殊含义。尝试为命令创建shell函数或bash脚本,而不是内联编写它。这应该让你做更复杂的事情,而不用担心shell逃逸的问题。

答案 1 :(得分:0)

sed 's/\([/_-][a-z]\)\([A-Z]*\)/\2\U\1/g'

echo $'./Assisted-or-Auto/Abstract-Render/assisted-or-auto_abstract-render_tiny-bubbles3.psd' \
| sed 's/\([/_-][a-z]\)\([A-Z]*\)/\2\U\1/g'

<强>输出

./Assisted-Or-Auto/Abstract-Render/Assisted-Or-Auto_Abstract-Render_Tiny-Bubbles3.psd

我只添加'/'以匹配初始小写字部分(我的sed说mismatched \( .. \)所以我在逻辑位置添加了1。

我希望这会有所帮助。

答案 2 :(得分:0)

轻微变化

$ input=Assisted-or-Auto/Abstract-Render/assisted-or-auto_abstract-render_tiny-bubbles3.psd
$ sed 's!\(/\|-\|_\)[a-z]!\U&!g' <<< "$input"
Assisted-Or-Auto/Abstract-Render/Assisted-Or-Auto_Abstract-Render_Tiny-Bubbles3.psd

可以用GNU sed做一点清洁

$ sed 's!(/|-|_)[a-z]!\U&!g' <<< "$input"

答案 3 :(得分:0)

避免反引号,因为这意味着你要求逃避问题。

正如已经指出的那样,反引号很可能在调用find之前生效。

使用$(),可以嵌套而不会有太多的转义,然后转义$中的$(command),以便它能够在调用后继续运行并传递给find。从那时起(假设find使用shell - 例如$SHELL - 来执行你的命令)事情会正常。

答案 4 :(得分:0)

这可能对您有用:

find . -name "*bubbles3.psd" | 
sed 'h;s/\(^\|[/_-]\)./\U&/g;H;g;s/^/cp -v /;s/\n/ /' |
bash

如果您想在执行前看到cp命令,请关闭最后一个管道| bash