为什么不
find . -type f -exec echo $(file={}; echo ${file:0:5}) \;
给出文件的前五个字符,如下所示:
find . -type f -exec bash -c 'echo ${1:0:5}' funcname {} \;
背景:
我正在尝试将一棵树上的图像批量转换为缩略图,并且我想通过在文件名末尾但在扩展名之前添加“_thumb”来动态重命名它们。对于一个文件来说,这个重命名过程很容易:
file='I am a picture.jpg'
mv \"$file\" \"${file%\.*}_thumb.${file##*\.}\"
(第二行扩展为mv "I am a picture.jpg" "I am a picture_thumb.jpg"
)
但是当我尝试将此命令封装-exec
在find(1)
我无法操作给出的文件名find
(简化示例):
find . -type f -exec ${{}:0:5}) \;
给出
bash: ${{}:0:5}: bad substitution
使用子 shell 我可以得到更进一步的结果:
find . -type f -exec echo $(file={}; echo ${file:0:5}) \;
这确实回显了文件名,但由于某种原因并没有执行字符串操作。
我终于找到了解决方案这篇文章:
find . -type f -exec bash -c 'echo ${1:0:5}' funcname {} \;
但我不明白当$(...)
构造不起作用时为什么这会起作用。
答案1
exec
按照说明操作:使用exec()
。除非被告知 ( -exec bash ...
),否则它不会涉及 shell,如果涉及,则仍然需要单引号来防止交互式 shell 解释变量插值。(shell 不是魔术,不知道你打算用其他东西来插值。)
例如,当您使用以下命令时:
查找 . -type f -exec echo$(文件={}; 回显 ${文件:0:5})\;
你的外壳第一的通过执行执行过程替换$(file={}; echo ${file:0:5})
,它只是输出{}
,然后执行最终命令:
查找 . -type f -exec echo{}\;