Расширение Bash переименовать рекурсивное - PullRequest
12 голосов
/ 31 января 2010

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

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

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

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

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

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

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

Ответы [ 6 ]

24 голосов
/ 26 апреля 2012

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

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

4 голосов
/ 18 марта 2013

Скрипт bash для переименования расширений файлов обычно

  #/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 .

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

  1. Создать файл, например называется ext-rename (без расширения, так что вы можете запустить его как команду), например, /usr/bin (убедитесь, что /usr/bin добавлен к вашему $PATH)
  2. запустить ext-rename [ext1] [ext2] в любом месте терминала, где [ext1] переименовывается из, а [ext2] переименовывается в. Пример использования: ext-rename so dylib, который переименует любой файл с расширением .so на то же имя, но с расширением .dylib.
4 голосов
/ 31 января 2010
for X in `find . -name "*.so"` 
do
 mv $X ${X/.so/.dylib}
done
3 голосов
/ 31 января 2010

Что плохого в том, что

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

если у вас Bash 4

#!/bin/bash

shopt -s globstar
shopt -s nullglob
for file in /path/**/*.so
do
 echo mv "$file"  "${file/%.so}.dylib"
done
0 голосов
/ 31 января 2010

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

#!/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 "."
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...