Поиск нескольких файлов рекурсивно и переименование в linux

у меня есть файлы, такие как a_dbg.txt, b_dbg.txt ... на Suse 10 система. Я хочу написать сценарий оболочки bash, который должен переименовать эти файлы, удалив из них" _dbg".

Google предложил мне использовать . Поэтому я выполнил команду rename _dbg.txt .txt *dbg* на CURRENT_FOLDER

моя CURRENT_FOLDER содержит следующие файлы.

CURRENT_FOLDER/a_dbg.txt
CURRENT_FOLDER/b_dbg.txt
CURRENT_FOLDER/XX/c_dbg.txt
CURRENT_FOLDER/YY/d_dbg.txt

после выполнения ,

CURRENT_FOLDER/a.txt
CURRENT_FOLDER/b.txt
CURRENT_FOLDER/XX/c_dbg.txt
CURRENT_FOLDER/YY/d_dbg.txt

это не делает рекурсивно, как сделать эту команду переименовать файлы во всех подкаталогах. Как XX и YY у меня будет так много подкаталогов, имя которых непредсказуемо. А также Мой CURRENT_FOLDER будете иметь некоторые другие файлы.

8 ответов


можно использовать find, чтобы найти все совпадающие файлы рекурсивно:

$ find . -iname "*dbg*" -exec rename _dbg.txt .txt '{}' \;

EDIT: какого '{}' и \; есть?

на -exec аргумент делает find execute rename для каждого соответствующего найденного файла. '{}' будет заменен на путь к файлу. Последний знак,\; есть только, чтобы отметить конец выражения exec.

все, что красиво описано в man-странице для поиска:

 -exec utility [argument ...] ;
         True if the program named utility returns a zero value as its
         exit status.  Optional arguments may be passed to the utility.
         The expression must be terminated by a semicolon (``;'').  If you
         invoke find from a shell you may need to quote the semicolon if
         the shell would otherwise treat it as a control operator.  If the
         string ``{}'' appears anywhere in the utility name or the argu-
         ments it is replaced by the pathname of the current file.
         Utility will be executed from the directory from which find was
         executed.  Utility and arguments are not subject to the further
         expansion of shell patterns and constructs.

маленький скрипт, который я написал, чтобы заменить все файлы .расширение txt на .расширение cpp в каталоге /tmp и подкаталогах рекурсивно

#!/bin/bash

for file in $(find /tmp -name '*.txt')
do
  mv $file $(echo "$file" | sed -r 's|.txt|.cpp|g')
done

с Баша:

shopt -s globstar nullglob
rename _dbg.txt .txt **/*dbg*

для рекурсивного переименования я использую следующие команды:

find -iname \*.* | rename -v "s/ /-/g"

Scipt выше можно написать в одной строке:

find /tmp -name "*.txt" -exec bash -c 'mv  $(echo "" | sed -r \"s|.txt|.cpp|g\")' '{}' \;

если вы просто хотите переименовать и не возражаете использовать внешний инструмент, то вы можете использовать rnm. Команда будет:

#on current folder
rnm -dp -1 -fo -ssf '_dbg' -rs '/_dbg//' *

-dp -1 сделает его рекурсивным для всех подкаталогов.

-fo подразумевает режим только файл.

-ssf '_dbg' поиск файлов с _dbg в имени файла.

-rs '/_dbg//' заменяет _dbg пустой строкой.

вы можете выполнить эту команду с пути ТЕКУЩАЯ_ПАПКА тоже:

rnm -dp -1 -fo -ssf '_dbg' -rs '/_dbg//' /path/to/the/directory

вы можете использовать этого ниже.

rename --no-act 's/\.html$/\.php/' *.html */*.html

классическое решение:

for f in $(find . -name "*dbg*"); do mv $f $(echo $f | sed 's/_dbg//'); done