Відніміть 1 з усіх імен файлів (перейменуйте їх) у каталозі.


17

У мене є каталог, який містить файли зображень на зразок таких імен

image1.jpg 
image2.jpg 
image3.jpg
...

На жаль, імена зображень повинні базуватися на нулі, так image1.jpgмає бути image0.jpg, image2.jpgповинно бути image1.jpgтощо.

Я можу написати скрипт для генерації команд mv на зразок цих, помістити їх у сценарій оболонки, а потім виконати їх -

mv image1.jpg image0.jpg
mv image2.jpg image1.jpg
mv image3.jpg image2.jpg
...

Але я гадаю, що в Unix є чистіший спосіб зробити це. Так що це?


6
Це насправді найпростіший спосіб зробити це, якщо немає прогалин. ( for i in $(seq 0 100); do mv image$[i+1].jpg image$i.jpg; done)
Рікі Бім

5
Чи важливий порядок зображень? Якщо ні, просто перейменуйте останнє зображення з imageN.jpgу, image0.jpgі ви закінчите.
jnovacho

@jnovacho, досить розумний! Але так, порядок зображень важливий.
Уес

Відповіді:


20

Старий добрий перейменування:

rename 's/(\d+)(\.jpg)/($1-1).$2/e' *

[Зауваження]

Номери зображень повинні бути більше 0.

У випадку, якщо зображення перевищують 9 і не мають нульових позначок 0, використовуйте $(ls -v1 *)для уникнення клобінгу. Запропоновано @arielf та помічено @Graeme.

Якщо ви сумніваєтесь, використовуйте також -vдля багатослівних та -nбез дій.


Що означає "е"?
Уес

3
'e' означає оцінити, розділ заміни буде оцінено. дивіться такожperlreref

6
Файли слід передавати у порядку зростання, щоб уникнути будь-якої клобери. Це буде добре, лише якщо файлів менше 10 (або якщо числа мають провідні нулі).
Graeme

Я вже помітив це, також 0у джерелах не повинно бути .

2
замініть *кінець на кінець, `ls -v1 *`і ви будете безпечніше від клобінгу. Він перейде від найнижчого до найвищого.
аріельф

6

Ви можете передавати згенеровані mvкоманди на bash. Тож вам не доведеться копіювати їх у сценарій та виконувати це. Побачити:

command_that_generates_mv_commands | bash

І все буде виконано, на що покладено bash.


Це не охайніше. :)Хоча вирішує проблему, тому +1.
JMCF125

5

Ви можете повторити вихід на ls, цей працює для вашого прикладу:

i=0 
for file in $(ls *.jpg | sort) ; do 
     mv $file $(echo $file | sed 's/[0-9]*.jpg$/'${i}'.jpg/')
     i=$((++i))
done

Ви повинні знаходитись на одному шляху з вашими файлами


1
Краще використовувати -iабо -nз mv, це запобіжить перезапис у крайових випадках.
Graeme

не sort -Vбуло б краще замість цього?
користувач80551

sortне буде працювати, він покаже, image10.jpgперед image1.jpgяким може виникнути проблема. Вам потрібно, sort -nk 1.8як у відповіді @ Graeme.
тердон

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

4

Наступне, здається, працює для всього, що відповідає шаблону imageNUMBER.jpg. Я поставив echoперед mvкомандою спочатку показати, що команда буде робити; щоб реально виконати перейменування, просто видалітьecho

for i in `ls image*.jpg|sort -V` ; do 
    x=`echo $i|sed -e "s/image\(.*\).jpg/\1/"`
    y=$(( $x - 1 ))
    echo mv -i $i image$y.jpg
done

У першому рядку ls image*.jpg|sort -Vзаголовок призведе до переліку файлів JPG із зростанням номерів у назві файлу. x=Лінія витягує номер з файлу. Потім y=рядок зменшує число на одиницю. Потім ім'я вхідного файлу та yномер використовуються в mvкоманді, де -iпрапор сповістить вас перед тим, як перезаписати файл.

Для мого власного невеликого тесту це дало вихід:

mv -i image1.jpg image0.jpg
mv -i image2.jpg image1.jpg
mv -i image123.jpg image122.jpg

Особисто я б запропонував перейменувати на інше ім'я файлу, оскільки тепер порядок обробки файлів може мати велике значення.


1
Краще використовувати -iабо -nз mv, це запобіжить перезапис у крайових випадках.
Graeme

Дуже гарна пропозиція, я відредагую відповідь
брм

У macOS слід використовувати sort -n, -Vопція не існує.
Вінсент Сит

4

Використання perlсценарію prename, який посилається на перейменування в дистрибутивах на основі Debian, також потребує GNU find/ sort. Файли розміщуються у порядку зростання, щоб запобігти перезапису.

find . -regex '\./image[0-9]+\.jpg' -print0 | sort -zV |
  xargs -0 rename -n 's/(\d+)\.jpg$/@{[$1-1]}.jpg/'

Видаліть, як -nтільки ви впевнені, що це робить те, що ви хочете. Попереджатиме про вже наявні файли, перш ніж це зробити. Однак, поки вони показують, що файли перейменовані у порядку зростання, конфліктів при запуску не буде.


У цьому файлі вже є проблеми з цим.
Уес

4

З zsh:

autoload zmv # (in ~/.zshrc)
zmv -Qf -n 'image(<->).jpg(n)' 'image$(($1-1)).jpg'

(видаляй, -nколи щасливий).

(n)полягає в сортуванні списку чисельно, щоб він image9.jpgбув перейменований раніше image10.jpg.

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