Я читал о массовом переименовании, изменении префикса и попробую со своими файлами. .

В этом случае я хотел бы удалить Old и заменить его на New

Тестовые файлы

01. Old Name.txt
02. Old Name.txt
03. Old Name.txt

Попытка 1

for f in *.txt
do
    mv "$f" "New${f#Old}"
done

Выход 1

New01. Old Name.txt
New02. Old Name.txt
New03. Old Name.txt

Попытка 2

for i in *.txt
do
    mv ${i} ${i/#Old/New}
done

Выход 2 (без изменений)

user@linux:~$ for i in *.txt
> do
> mv ${i} ${i/#Old/New}
> done
mv: target 'Name.txt' is not a directory
mv: target 'Name.txt' is not a directory
mv: target 'Name.txt' is not a directory
user@linux:~$ 

Что не так с моим решением?

Desired Output

01. New Name.txt
02. New Name.txt
03. New Name.txt
0
icarus 5 Окт 2019 в 08:37
1
Просто используйте команду perl rename. Она такая же «встроенная», как и команда mv. то есть ни одна из них не является «встроенной» в bash, обе они являются внешними командами, запускаемыми из оболочки. И, как и GNU coreutils (который содержит mv), он доступен в предварительно упакованном виде для большинства, если не для всех, дистрибутивов Linux. rename 's/Old/New/' *.txt
 – 
cas
5 Окт 2019 в 09:10
1
Кстати, ваша вторая попытка не удалась, потому что вы не указали аргументы в двойных кавычках. Попробуйте mv "${i}" "${i/Old/New}". См. Почему мой сценарий оболочки задыхаетесь от пробелов или других специальных символов?
 – 
cas
5 Окт 2019 в 09:13
Спасибо @cas. Если я процитирую это, я получу эту ошибку mv: '01. Old Name.txt' and '01. Old Name.txt' are the same file
 – 
user264359
5 Окт 2019 в 09:21
rename не является встроенным .. необходимо установить его. У меня проблема с несколькими серверами, из-за чего мы не можем просто установить на них что-то новое Command 'rename' not found, but can be installed with: sudo apt install rename
 – 
user264359
5 Окт 2019 в 09:21
Как я указал, mv также не является "встроенным".
 – 
cas
5 Окт 2019 в 09:24

1 ответ

Лучший ответ
  1. Процитируйте свои переменные. Кроме того, используйте ${i/Old/New} без символа решетки (#) перед Old. # заставляет поиск начинаться с начала имени файла, но ни один из файлов не начинается с Old, все они начинаются с 0.

    $ touch "01. Old Name.txt" "02. Old Name.txt" "03. Old Name.txt"
    $ for i in *.txt ; do mv -v "$i" "${i/Old/New}" ; done
    renamed '01. Old Name.txt' -> '01. New Name.txt'
    renamed '02. Old Name.txt' -> '02. New Name.txt'
    renamed '03. Old Name.txt' -> '03. New Name.txt'
    
  2. Установите и используйте утилиту Perl rename (например, sudo apt-get install rename в Debian и его производных). Это намного лучше, чем массовое переименование своими руками.

1
icarus 5 Окт 2019 в 09:42
Понял, в моем скрипте было лишнее # .. спасибо все работает!
 – 
user264359
5 Окт 2019 в 10:29
1
Кроме того, используйте mv -i или -n в такой операции автоматического/массового перемещения/переименования, чтобы избежать риска потери данных в случае возникновения конфликтов имен (или ошибок при переименовании).
 – 
Gordon Davisson
5 Окт 2019 в 10:50
1
И это еще одна причина использовать команду perl rename. Он не будет перезаписывать существующие файлы, если вы не сделаете это принудительно с помощью -f, --force.
 – 
cas
5 Окт 2019 в 12:53