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 "."