Перейменуйте кілька файлів за допомогою сценарію Bash


27

Я хочу перейменувати кілька файлів в одному каталозі за допомогою сценарію Bash. Назви файлів такі:

file2602201409853.p
file0901201437404.p  
file0901201438761.p  
file1003201410069.p  
file2602201410180.p

Я хочу перейменувати у такий формат:

file2503201409853.p
file2503201437404.p  
file2503201438761.p  
file2503201410069.p  
file2503201410180.p

Я читав про команду перейменування і намагався зробити це так, але це нічого не робить, я думаю, що у мене є питання щодо синтаксису. Потім я прочитав, що ви можете зробити цикл за допомогою команди mv наступним чином:

for file in cmpsms*2014*.p; do
    mv "$file" "${file/cmpsms*2014*.p/cmpsms25032014*.p}"
done

Але я не можу перейменувати файли. Що я роблю неправильно?



2
Ви не можете мати вираз шаблону з правого боку виразу заміни параметра розширення. Що ви очікували бути там, де *це?
kojiro

@Kiwy Це питання стосується видалення частини імені файлу. Ерго, дуже сумнівно, дублікат.
CVn

2
Наступного разу, будь ласка, опишіть зміни файлу, які ви хочете внести (я повинен був переглянути це справедливо, перш ніж побачити відмінності та схожість). Приклади хороші, але опис , а також приклади ще краще.
CVn

Відповіді:


42

Ви мали рацію розглянути питання про перейменування спочатку. Синтаксис трохи дивний, якщо ви не звикли до регулярних виразів, але це, безумовно, найшвидший / найкоротший маршрут, як тільки ви дізнаєтеся, що робите:

rename 's/\d{4}/2503/' file*

Це просто відповідає першим 4 числам і замінює їх на ті, які ви вказали.

І тестовий ремінь ( -vnозначає бути багатослівним, але нічого не робити ), використовуючи ваші імена файлів:

$ rename 's/\d{4}/2503/' file* -vn
file0901201437404.p renamed as file2503201437404.p
file0901201438761.p renamed as file2503201438761.p
file1003201410069.p renamed as file2503201410069.p
file2602201409853.p renamed as file2503201409853.p
file2602201410180.p renamed as file2503201410180.p

8
Зауважте, що це перейменування Perl на Debian та похідні (Ubuntu, Mint,…). В інших дистрибутивах Linux rename- це зовсім інший інструмент перейменування файлів (який Debian поставляється як rename.ul).
Жил "ТАК - перестань бути злим"

Якщо у вашому розповсюдженні не вистачає такого інструменту, подивіться на відповідь @Michael Campbell. Я думаю, що кожен дистрибутив замінює дефолт, renameяк це робив Debian.
Астер

25

Для цього слід зробити фокус:

for f in file*; do mv $f ${f/${f:4:8}/25032014}; done

Він замінює рядок між 4-м та 12-м символом на "25032014".


це for f in file*; do mv $f ${f/${f:4:4}/2503}; doneтакож працює.
Avinash Raj

Це мило. Якщо ви просто хочете зробити звичайне слово для заміни слова, воно працює як sed. наприкладfor f in *Huge*; do mv $f ${f/Huge/Monstrous}; done
Ерік

1
@Eric - Вашу відповідь я розмістив як альтернативу, тому що вважаю це більш зрозумілим та елегантним. Якщо ви також хочете опублікувати його як відповідь - я видалю свою. Спасибі!
Yehosef


Це дає мені помилку: "mv: target" FILE_NAME "- це не каталог"
Обрі

10

це дійсно відповідь @ Еріка зверху - але це елегантна відповідь, тому я повторюю це як належну відповідь, щоб привернути до неї більше уваги.

for f in *Huge*; do mv $f ${f/Huge/Monstrous}; done

1
ptrn='file[0-9][0-9][0-9][0-9]2014[0-9][0-9][0-9][0-9][0-9].p'
path=/dir
( set -- "${path}/"${ptrn} ; for f ; do {
    echo "mv ${path}/${f} \
        ${path}/file25032014${f#2014}" 
} ; done )

Це повинно зробити трюк. Зауважте - я не маю звички передавати масові телевізійні команди - як написано, це просто відлуння. Вам доведеться розібратися в цьому, перш ніж воно запрацює.


1

Простий рідний спосіб зробити це без циклу, з обходом каталогу :

find -type f | xargs -I {} mv {} {}.txt

Він буде перейменовувати кожен файл на місці.

А нижче робочий приклад з паралелізацією :

find -name "file*.p" | parallel 'f="{}" ; mv -- {} ${f:0:4}2503${f:8}'

Першим підходом було уявити краще рішення. Якщо ви хочете, щоб робоча команда зробила:
dtrckd

find -type f -name "file*.p" | parallel 'ext="{}" ; mv -- {} ${ext:0:4}2503${ext:8}'
dtrckd

0

Якщо ви виявили, що ви багато чого робите, шукайте "rename.pl". Це сценарій perl, але дозволяє просто подати його на код perl (наприклад, як /// вираз), і він зробить масове перейменування на основі цього виразу чи коду.

Тут є основна версія: http://stackoverflow.org/wiki/Rename.pl, але існують інші версії, що плавають по мережі. Це було віками, століттями та століттями.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.