Bash скрипт для рекурсивного поиска и изменения расширений файлов

Я хочу собрать небольшой скрипт, который изменяет расширение всех файлов в каталоге с определенным расширением, например .png или .gif .

Я думаю, что сценарий просто принимает 2 аргумента при исполнении. Одним из них является расширение для изменения, а вторым является расширение для изменения.

Первоначально я думал, что буду использовать read чтобы получить целевой каталог, но это делает это слишком сложным, поэтому вместо этого я просто заставляю его работать в текущем каталоге. Я использую Debian 9, поэтому команда rename недоступна.

Это работает с фиксированным контентом (от txt до rdf):

 $ find -depth -name "*.txt" -exec sh -c 'mv "$1" "${1%.txt}.rdf"' _ {} \; 

однако я не могу понять, как изменить расширения содержимого переменных, которые наследуют переданные аргументы. по умолчанию это будет $ 1 $ 2, но когда я изменю его, как показано ниже, он не будет работать.

 $ find -depth -name "*.$1" -exec sh -c 'mv "$1" "${1%.$1}.$2"' _ {} \; 

Этот пример просто добавляет. до конца всех подходящих файлов. Что мне здесь не хватает?

 #!/bin/sh find . -depth -name "*.$1" -exec sh -c ' from=$1 to=$2 shift 2 for pathname do mv "$pathname" "${pathname%.$from}.$to" done' sh "$1" "$2" {} + 

Это позволяет внутреннему сценарию принимать суффиксы имени файла в качестве параметров, а также список путей для изменения. Во внутреннем скрипте вы извлекаете два суффикса и удаляете их из списка аргументов, а затем перебираете имена патчей, данные скрипту из find .

Менее эффективен (один вызов sh -c каждого пути вместо циклического повторения по пакету из них):

 #!/bin/sh find . -depth -name "*.$1" -exec sh -c 'mv "$3" "${3%.$1}.$2"' sh "$1" "$2" {} ';' 

В качестве примечания: используйте привычку sh или find-sh или другое соответствующее имя для нулевого аргумента внутреннего скрипта. Этот аргумент используется в сообщениях об ошибках из скрипта, и получение сообщения об ошибке от _ может привести к путанице при некоторых обстоятельствах.