Подтвердить что ты не робот

Найти и заменить имя файла рекурсивно в каталоге

Я хочу переименовать все файлы в папке, которая начинается с 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

Правильно ли это делается?

4b9b3361

Ответ 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. Многочисленные вилки и повторные реализации: