Подтвердить что ты не робот

Bash переименовать расширение рекурсивное

Я знаю, что таких вещей много, но либо они не работают рекурсивно, либо огромны.

Вот что я получил:

find . -name "*.so" -exec mv {} `echo {} | sed s/.so/.dylib/` \;

Когда я просто запускаю часть поиска, он дает мне список файлов. Когда я запускаю sed, он заменяет любой .so на .dylib. Когда я запускаю их вместе, они не работают.

Я заменил mv на эхо, чтобы узнать, что произошло:

./AI/Interfaces/C/0.1/libAIInterface.so ./AI/Interfaces/C/0.1/libAIInterface.so

Ничего не заменено вообще!
Что не так?

4b9b3361

Ответ 1

Это сделает все правильно:

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}, неверны, поскольку они ошибочно переименовывают первое вхождение .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) Он будет следовать символическим ссылкам в подкаталоги и ссылки на целевые файлы и переименовывать целевой файл, а не саму ссылку (поведение по умолчанию для поиска - это обработка самой символической ссылки, а не файла, на который указывает ссылка).

Ответ 2

A bash script для переименования расширений файлов вообще

  #/bin/bash
  find -L . -type f -name '*.'$1 -print0 | while IFS= read -r -d '' file; do
      echo "renaming $file to $(basename ${file%.$1}.$2)";
      mv -- "$file" "${file%.$1}.$2";
  done

Кредиты aps2012.

Использование

  • Создать файл, например. называется ext-rename (без расширения, поэтому вы можете запускать его как команду), например. /usr/bin (убедитесь, что /usr/bin добавлен в $PATH)
  • запустите ext-rename [ext1] [ext2] в любом месте терминала, где [ext1] переименовывает и [ext2] переименовывает. Пример использования: ext-rename so dylib, который переименует любой файл с расширением .so с тем же именем, но с расширением .dylib.

Ответ 3

for X in `find . -name "*.so"` 
do
 mv $X ${X/.so/.dylib}
done

Ответ 4

Что не так, так это то, что

echo {} | sed s/.so/.dylib/
выполняется только один раз, до запуска find, sed задается {} на его входе, который не соответствует /.so/ и остается неизменным, поэтому ваша итоговая командная строка
найти. -name "*.so" -exec mv {} {}

Ответ 5

если у вас Bash 4

#!/bin/bash

shopt -s globstar
shopt -s nullglob
for file in /path/**/*.so
do
 echo mv "$file"  "${file/%.so}.dylib"
done

Ответ 6

Ему нужна рекурсия:

#!/bin/bash

function walk_tree {
    local directory="$1"
    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 "."