Bash переименовать расширение рекурсивно
Я знаю, что вокруг много таких вещей, но либо они не работают рекурсивно, либо они огромны.
вот что я получил:
find . -name "*.so" -exec mv {} `echo {} | sed s/.so/.dylib/` ;
когда я просто запускаю часть поиска, она дает мне список файлов. Когда я запускаю часть sed, она заменяет любую .так и с .dylib нужна. Когда я управляю ими вместе, они не работают.
Я заменил mv на echo, чтобы посмотреть, что произошло:
./AI/Interfaces/C/0.1/libAIInterface.so ./AI/Interfaces/C/0.1/libAIInterface.so
ничего не заменяется вообще!
Что случилось?
6 ответов
это все правильно:
find -L . -type f -name "*.so" -print0 | while IFS= read -r -d '' FNAME; do
    mv -- "$FNAME" "${FNAME%.so}.dylib"
done
правильно, мы имеем в виду:
1) он переименует только расширение файла (из-за использования ${FNAME%.so}.dylib). Все остальные решения с использованием ${X/.so/.dylib} неверны, поскольку они ошибочно переименовывают первое вхождение of .so В имя файла (например,x.so.so переименован в x.dylib.so, или, еще хуже, ./libraries/libTemp.so-1.9.3/libTemp.so переименован в ./libraries/libTemp.dylib-1.9.3/libTemp.so - сообщение об ошибке).
2) он будет обрабатывать пробелы и любые другие специальные символы в именах файлов (кроме двойных кавычек).
3) он не будет изменять каталоги или другие специальные файлы.
4) он будет следовать символическим ссылкам в подкаталоги и ссылкам на целевые файлы и переименовывать целевой файл, а не саму ссылку (поведение по умолчанию find должно обрабатывать символическую ссылку, а не файл, на который указывает ссылка).
скрипт bash для переименования расширений файлов вообще
  #/bin/bash
  find -L . -type f -name '*.' -print0 | while IFS= read -r -d '' file; do
      echo "renaming $file to $(basename ${file%.}.)";
      mv -- "$file" "${file%.}.";
  done
кредиты aps2012.
использование
- создайте файл, например под названием 
ext-rename(нет расширения, поэтому вы можете запустить его как команду), например,/usr/bin(убедитесь, что/usr/binдобавляется$PATH) -  run 
ext-rename [ext1] [ext2]в любом месте в терминале, где[ext1]переименование из и[ext2]- это называется. Пример использования:ext-rename so dylib, который переименует любой файл с расширением.soС тем же именем, но с расширением.dylib. 
что не так, что
echo {} | sed s/.so/.dylib/
выполняется только один раз, перед find запускается, sed дано {} на его входе, который не соответствует /.so/ и остается неизменным, поэтому ваша результирующая командная строка
find . -name "*.so" -exec mv {} {}
если у вас есть Bash 4
#!/bin/bash
shopt -s globstar
shopt -s nullglob
for file in /path/**/*.so
do
 echo mv "$file"  "${file/%.so}.dylib"
done
ему нужна рекурсия:
#!/bin/bash
function walk_tree {
    local directory=""
    local i
    for i in "$directory"/*; 
        do
            if [ "$i" = . -o "$i" = .. ]; then 
                continue
            elif [ -d "$i" ]; then  
            walk_tree "$i"  
            elif [ "${i##*.}" = "so" ]; then
                echo mv $i ${i%.*}.dylib    
            else
                continue
            fi
        done    
}
walk_tree "."