Найти и заменить имя файла рекурсивно в каталоге
Я хочу переименовать все файлы в папке, которая начинается с 123_xxx.txt
до xxx.txt
.
Например, в моем каталоге есть:
123_xxx.txt
123_yyy.txt
123_zzz.txt
I want to rename all files as:
xxx.txt
yyy.txt
zzz.txt
Я видел несколько полезных сценариев bash на этом форуме, но я все еще запутался, как использовать его для моего требования.
Предположим, что я использую:
for file in `find -name '123_*.txt'` ; do mv $file {?.txt} ; done
Правильно ли это делается?
Ответы
Ответ 1
Сделайте это так:
find . -name '123*.txt' -type f -exec bash -c 'mv "$1" "${1/\/123_//}"' -- {} \;
Преимущества:
- Нет труб, нет прочтений, нет возможности взломать неверные имена файлов.
- Только один нестандартный инструмент или функция: bash.
Ответ 2
find -name "123*.txt" -exec rename 's/^123_//' {} ";"
сделает это. Нет AWK, нет, нет xargs, но переименовать, очень полезную команду из Perl lib. Он не всегда включен в Linux, но его легко установить из репозиториев.
Ответ 3
вы можете проверить инструмент "переименовать"
например
rename 's/^123_//' *.txt
или (требуется gawk)
find . -name '123_*.txt'|awk '{print "mv "$0" "gensub(/\/123_(.*\.txt)$/,"/\\1","g");}'|sh
тест
kent$ tree
.
|-- 123_a.txt
|-- 123_b.txt
|-- 123_c.txt
|-- 123_d.txt
|-- 123_e.txt
`-- u
|-- 123_a.txt
|-- 123_b.txt
|-- 123_c.txt
|-- 123_d.txt
`-- 123_e.txt
1 directory, 10 files
kent$ find . -name '123_*.txt'|awk '{print "mv "$0" "gensub(/\/123_(.*\.txt)$/,"/\\1","g");}'|sh
kent$ tree
.
|-- a.txt
|-- b.txt
|-- c.txt
|-- d.txt
|-- e.txt
`-- u
|-- a.txt
|-- b.txt
|-- c.txt
|-- d.txt
`-- e.txt
1 directory, 10 files
Ответ 4
Если вы хотите заменить строку в имени файла с именем foo на bar, вы можете использовать ее в linux ubuntu, измените тип файла для своих нужд
find -name "*foo*.filetype" -exec rename 's/foo/bar/' {} ";"
Ответ 5
Небольшое изменение в графстве Кент, который не требует Gawk и немного более удобным для чтения, (хотя, тот спорно..)
find . -name "123*" | awk '{a=$1; gsub(/123_/,""); printf "mv \"%s\" \"%s\"\n", a, $1}' | sh
Ответ 6
Если у вас нет новых строк в именах файлов:
find -name '123_*.txt' | while IFS= read -r file; do mv "$file" "${file#123_}"; done
Для действительно безопасного способа, если ваш find
поддерживает флаг -print0
(GNU find
):
find -name '123_*.txt' -print0 | while IFS= read -r -d '' file; do mv "$file" "${file#123_}"; done
Ответ 7
Чтобы расширить Sorpigal answer, если вы хотите заменить 123_
на hello_
, вы можете использовать
find . -name '123*.txt' -type f -exec bash -c 'mv "$1" "${1/\/123_/\/hello_}"' -- {} \;
Ответ 8
Вы можете сделать небольшой сценарий bash для этого. Создайте файл с именем recursive_replace_filename
с этим содержанием:
#!/bin/bash
if test $# -lt 2; then
echo "usage: 'basename $0' <to_replace> <replace_value>"
fi
for file in 'find . -name "*$1*" -type f'; do
mv "'$file'" "${file/'$1'/'$2'}"
done
Сделать исполняемый файл прогоном:
$ chmod +x recursive_replace_filename
$ ./recursive_replace_filename 123_ ""
Имейте в виду, что этот сценарий может быть опасным, убедитесь, что вы знаете, что он делает, в какой папке вы его выполняете и с какими аргументами. В этом случае все файлы в текущей папке, рекурсивно содержащие 123_
будут переименованы.
Ответ 9
Использование переименования из util-linux 2.28.2 Мне пришлось использовать другой syntaxt:
find -name "*.txt" -exec rename -v "123_" "" {} ";"
Ответ 10
Попробовал ответ выше, но он не работал для меня, потому что у меня была строка внутри папок и имен файлов одновременно, вот что я сделал с помощью следующего скрипта bash:
for fileType in d f
do
find -type $fileType -iname "stringToSearch*" |while read file
do
mv $file $( sed -r "s/stringToSearch/stringToReplaceWith/" <<< $file )
done
done
Сначала я заменил имя папки внутри, а затем имя файла.
Ответ 11
Если имена фиксированы, вы можете посетить каждый каталог и выполнить переименование в подоболочке (чтобы избежать изменения текущего каталога) довольно просто. Вот как я переименовал кучу файлов new_paths.json
каждый в paths.json
:
for file in $(find root_directory -name new_paths.json)
do
(cd $(dirname $file) ; mv new_paths.json paths.json)
done
Ответ 12
используя приведенные выше примеры, я использовал это для замены части имени файла... это использовалось для переименования различных файлов данных в каталоге из-за смены имени поставщика.
находить. -name 'o3_cloudmed_.' -type f -exec bash -c 'mv "$ 1" "$ {1/cloudmed/revint}"' - {} \;
Ответ 13
prename s/^123_// 123_*
См. prename в официальной вики Perl5. Скопируйте для удобства:
prename
- A script, который переименовывает файлы в соответствии с регулярным выражением. (Где был оригинал опубликован?) Первоначально названный rename, он встречается главным образом как prename, потому что исходный столкновение с командой rename из пакета util-linux
. Многочисленные вилки и повторные реализации: