7

Почему не

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

Используя подоболочку, я получаю немного дальше:

find . -type f -exec echo $(file={}; echo ${file:0:5}) \;

это повторяет имя файла, но по какой-то причине не выполняет манипуляции со строками.

Я наконец нашел решение в этом посте ТАК:

find . -type f -exec bash -c 'echo ${1:0:5}' funcname {} \;

но я не понимаю, почему это будет работать, когда конструкция $(...) не работает.

1 ответ1

6

exec делает то, что говорит: использует exec() . Он не включает в себя оболочку, если ей не сообщается (-exec bash ...), и если это так, вам все равно потребуются одинарные кавычки, чтобы ваша интерактивная оболочка не могла интерпретировать переменные интерполяции. (Оболочка не волшебная и не знает, что вы предполагали, что они будут интерполированы чем-то другим.)


Например, когда вы используете следующую команду:

find . -type f -exec echo $(file={}; echo ${file:0:5}) \;

Ваша оболочка сначала выполняет подстановку процесса, выполнив $(file={}; echo ${file:0:5}) , который просто выводит {} , а затем выполняет последнюю команду:

find . -type f -exec echo {} \;

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .