Поиск нескольких файлов рекурсивно и переименование в 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
для рекурсивного переименования я использую следующие команды:
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