2011-01-04 4 views
1

У меня есть 4 файлы со следующими именами в разных каталогах и подкаталогахимена файлов Rename в текущем каталоге и во всех подкаталогах

tag0.txt, tag1.txt, tag2.txt and tag3.txt 

и хотят переименовать их в качестве tag0a.txt, tag1a.txt ,tag2a.txt and tag3a.txt во всех каталогах и подкаталогах.

Может ли кто-нибудь помочь мне с помощью сценария оболочки?

Cheers

ответ

0

Действительно ли это достаточно?


[email protected]repid:/tmp$ find . -name tag?.txt 
./a/tag0.txt 
./b/tagb.txt 
./c/tag1.txt 
./c/d/tag3.txt 
[email protected]:/tmp$ for txtfile in $(find . -name 'tag?.txt'); do \ 
mv $txtfile ${txtfile%%.txt}a.txt; done 
[email protected]:/tmp$ find . -name tag*.txt 
./a/tag0a.txt 
./b/tagba.txt 
./c/d/tag3a.txt 
./c/tag1a.txt 

Не на самом деле поставить обратную косую черту в команду, и если вы делаете, ожидать приглашения «>» на следующей строке. Я не делал этого вывода, чтобы избежать путаницы, но я не хотел, чтобы кто-то тоже просканировал.

+1

он не будет работать, если пробелы находятся в именах каталогов, хотя –

+0

Спасибо за вашу помощь. Если я хорошо понимаю, фактические команды: «для txtfile в $ (find. -name« tag? .txt »); do \ mv $ txtfile $ {txtfile %%. Txt} a.txt; done" – Tony

+0

yes, это верно. –

3
$ shopt -s globstar 
$ rename -n 's/\.txt$/a\.txt/' **/*.txt 
foo/bar/tag2.txt renamed as foo/bar/tag2a.txt 
foo/tag1.txt renamed as foo/tag1a.txt 
tag0.txt renamed as tag0a.txt 

Удалить -n переименовать после проверки результата - это вариант «сухого хода».

+1

Возможно, вам понадобится '**/tag [0123] .txt' вместо' **/*. Txt' в соответствии с OP –

1

Вот скрипт POSIX оболочки (проверено с тире):

visitDir() { 
    local file 
    for file in "$1"/*; do 
      if [ -d "$file" ]; then 
        visitDir "$file"; 
      else 
        if [ -f "$file" ] && echo "$file"|grep -q '^.*/tag[0-3]\.txt$'; then 
          newfile=$(echo $file | sed 's/\.txt/a.txt/') 
          echo mv "$file" "$newfile" 
        fi 
      fi 

    done 
} 

visitDir . 

Если вы можете использовать bashisms, просто замените внутренний IF с:

if [[ -f "$file" && "$file" =~ ^.*/tag[0-3]\.txt$ ]]; then 
    echo mv "$file" "${file/.txt/a.txt}" 
fi 

Первая проверка, что результат того, что вы ожидали, тогда, возможно, удалите «эхо» перед командой mv.

+0

+1 для переносимости – Sorpigal

3

Это, конечно, может быть сделано с находкой:

find . -name 'tag?.txt' -type f -exec bash -c 'mv "$1" ${1%.*}a.${1##*.}' -- {} \; 
+0

Должен заметить, что этой версии все равно, что расширение , только что он имеет один. Выбор другого набора файлов для переименования будет работать. – Sorpigal

+0

+1 для ответа с использованием параметра Expansion – SiegeX

1

Используя версию сценария Perl из rename, которые могут быть в вашей системе:

find . -name 'tag?.txt' -exec rename 's/\.txt$/a$&/' {} \; 

Используя двоичный исполняемый версию rename:

find . -name 'tag?.txt' -exec rename .txt a.txt {} \; 

, который меняет первое появление «.txt». Поскольку имена файлов ограничены аргументом -name, это не будет проблемой.

Смежные вопросы