我想要重命名的目录结构中有大量文件。
文件名采用以下格式:
" 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)"符号具有相同的效果
由于
答案 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