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
Ничего не заменено вообще!
Что не так?
Ответы
Ответ 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 "."