Zbiorowe zmiany nazw plików


25

Mam kilka plików:

10.3.100.179_01_20161018_230014_5335.jpg
10.3.100.179_01_20161018_231514_0814.jpg
10.3.100.179_01_20161018_233014_5706.jpg
10.3.100.179_01_20161018_234514_0896.jpg
10.3.100.179_01_20161018_230114_5395.jpg
10.3.100.179_01_20161018_231614_1145.jpg
10.3.100.179_01_20161018_233114_6047.jpg
10.3.100.179_01_20161018_234614_0547.jpg
10.3.100.179_01_20161018_230114_5492.jpg
10.3.100.179_01_20161018_231614_1264.jpg
10.3.100.179_01_20161018_233114_6146.jpg
10.3.100.179_01_20161018_234614_0658.jpg
10.3.100.179_01_20161018_230214_5630.jpg
10.3.100.179_01_20161018_231714_7135.jpg

Chcę zmienić nazwę w tym formacie:

10.4.100.135_01_20161013131108389_TIMING.jpg
10.4.100.135_01_20161013131111390_TIMING.jpg
10.4.100.135_01_20161013131114401_TIMING.jpg
10.4.100.135_01_20161013131117431_TIMING.jpg
10.4.100.135_01_20161013131120418_TIMING.jpg
10.4.100.135_01_20161013131123461_TIMING.jpg
10.4.100.135_01_20161013131126511_TIMING.jpg

Musi usunąć _znacznik czasu i dodać _TIMING.



5
Proszę używać spójnych przykładów w swoich pytaniach. Wygląda na to, że chcesz zamienić 10.3.100.179z 10.4.100.135. Czy tego właśnie chcesz, czy chcesz po prostu usunąć _TIMINGi _od czasu?
terdon

3
Dobry czas, aby przypomnieć ludziom, że istnieje standard iso8601 dla dat (który działa zarówno dla nazw plików ORAZ dla wpisów do dziennika) ^^ Więc może powinieneś ponownie rozważyć zmianę nazwy na: RRRR-MM-DDThh: mm: ss.mmm (ex : twój pierwszy plik stałby się: 10.4.100.135_01_2016-10-13T13:11:08.389_TIMING.jpg(a „TIMING” mógłby nawet zostać usunięty, ponieważ teraz wygląda wyraźnie jak data i godzina (i milisekundy), szczególnie gdy standard staje się bardziej rozpowszechniony. T jest częścią standardu, a ja dorastał, aby to lubić (i wyjęcie go łamie standard ^^)
Olivier Dulac

@OlivierDulac Nie polecam używania :w nazwie pliku. Wierzę, że Windows go nie obsługuje.
Justin,

@ Justin dobry punkt. standard zaleca upuszczenie go dla nazw plików. Dałem wersję w pliku
Olivier Dulac

Odpowiedzi:


38

Zainstaluj renameutilsi używaj qmvz ulubionym edytorem tekstu.

qmvładuje wszystkie nazwy do edytora, a po zapisaniu i zamknięciu stosuje zmiany do rzeczywistych plików. Jeśli zmiany są niespójne (np. Dwa pliki mają tę samą nazwę), zostanie przerwane bez dotykania czegokolwiek. Obsługuje również poprawnie okrągłe zmiany nazw.

Zwyklę robię:

$ qmv -f do

tak, że pokazuje tylko jedną kolumnę nazw (do: only-destination-only). Oto jak to wygląda:

qmw

Jeśli połączysz go z wieloma kursorami SublimeText, Atom lub Visual Studio Code, będzie to bardzo ładne i potężne narzędzie do masowej zmiany nazw. Na przykład zrobiłbyś to dla Atom EDITOR="atom -w" qmv -f do.


1
Witamy w askUbuntu! To jest takie fajne!
αғsнιη

Podpisano to tylko do +! to. ;)
J. Allan

2
Wow, fajne narzędzie i ładna animacja GIF. Świetna pierwsza odpowiedź, zapraszamy! :)
Byte Commander

1
Dzięki @KasiyA za wstawienie obrazu i wszystkim innym za pozytywne komentarze.
ateijelo

1
@kasperd Tak, ostrzeże, że plan zmiany nazwy zawiera błędy i otworzy interaktywną konsolę, w której można podjąć dalsze działania.
ateijelo

27

Użyj rename...

rename -n 's/^([0-9]+\.[0-9]\.[0-9]+\.[0-9]+_[0-9]+_)([0-9]+)_([0-9]+)_([0-9]+)\.jpg/$1$2$3$4_TIMING\.jpg/' *

Dzięki -ntemu wygeneruje to, co zrobi bez wprowadzania żadnych zmian:

rename(10.3.100.179_01_20161018_230014_5335.jpg, 10.3.100.179_01_201610182300145335_TIMING.jpg)
rename(10.3.100.179_01_20161018_231514_0814.jpg, 10.3.100.179_01_201610182315140814_TIMING.jpg)
rename(10.3.100.179_01_20161018_233014_5706.jpg, 10.3.100.179_01_201610182330145706_TIMING.jpg)
rename(10.3.100.179_01_20161018_234514_0896.jpg, 10.3.100.179_01_201610182345140896_TIMING.jpg)

Jeśli wszystko wygląda poprawnie, usuń -n

$ rename 's/^([0-9]+\.[0-9]\.[0-9]+\.[0-9]+_[0-9]+_)([0-9]+)_([0-9]+)_([0-9]+)\.jpg/$1$2$3$4_TIMING\.jpg/' *
$ ls
10.3.100.179_01_201610182300145335_TIMING.jpg  10.3.100.179_01_201610182330145706_TIMING.jpg
10.3.100.179_01_201610182315140814_TIMING.jpg  10.3.100.179_01_201610182345140896_TIMING.jpg

Wyjaśnienie ...

  • s/something/something_else/ wyszukaj i zamień
  • ^ początek nazwy (zakotwiczenie)
  • [0-9] Jakikolwiek numer
  • + jeden lub więcej poprzedzających znaków
  • \.dosłowny .(bez \tego pasuje dowolny znak)
  • () zachować tę część
  • $1$2$3$3 wstecz odniesienia do rzeczy pasujących wcześniej i zachowanych ()

Uwaga: *na końcu polecenia pasuje wszystkie widoczne pliki w bieżącym katalogu. W razie potrzeby użyj bardziej odpowiedniego globu.


2
W niektórych dystrybucjach to polecenie jest dostępne jako prename(p dla perla, ponieważ pierwszy argument jest wyrażeniem perla)
Peter Cordes

12

mmv można to zrobić w następujący sposób:

mmv '*_*_*_*_*.jpg' '#1_#2_#3#4#5_TIMING.jpg'

10.3.100.179_01_20161018_230014_5335.jpg 10.3.100.179_01_201610182300145335_TIMING.jpg

# 1, # 2, # 3, ... odnosi się tutaj do pasującego „*” tutaj.

Jest jeszcze krótszy z:

mmv '*_*_*.jpg' '#1#2#3_TIMING.jpg'

9

Inne renamepodejście:

$ rename -n 's/(.*)_(.*)_(.*)\./$1$2$3_TIMING./' *
10.3.100.179_01_20161018_230014_5335.jpg -> 10.3.100.179_01_201610182300145335_TIMING.jpg
10.3.100.179_01_20161018_230114_5395.jpg -> 10.3.100.179_01_201610182301145395_TIMING.jpg
10.3.100.179_01_20161018_230114_5492.jpg -> 10.3.100.179_01_201610182301145492_TIMING.jpg
10.3.100.179_01_20161018_230214_5630.jpg -> 10.3.100.179_01_201610182302145630_TIMING.jpg
10.3.100.179_01_20161018_231514_0814.jpg -> 10.3.100.179_01_201610182315140814_TIMING.jpg
10.3.100.179_01_20161018_231614_1145.jpg -> 10.3.100.179_01_201610182316141145_TIMING.jpg
10.3.100.179_01_20161018_231614_1264.jpg -> 10.3.100.179_01_201610182316141264_TIMING.jpg
10.3.100.179_01_20161018_231714_7135.jpg -> 10.3.100.179_01_201610182317147135_TIMING.jpg
10.3.100.179_01_20161018_233014_5706.jpg -> 10.3.100.179_01_201610182330145706_TIMING.jpg
10.3.100.179_01_20161018_233114_6047.jpg -> 10.3.100.179_01_201610182331146047_TIMING.jpg
10.3.100.179_01_20161018_233114_6146.jpg -> 10.3.100.179_01_201610182331146146_TIMING.jpg
10.3.100.179_01_20161018_234514_0896.jpg -> 10.3.100.179_01_201610182345140896_TIMING.jpg
10.3.100.179_01_20161018_234614_0547.jpg -> 10.3.100.179_01_201610182346140547_TIMING.jpg
10.3.100.179_01_20161018_234614_0658.jpg -> 10.3.100.179_01_201610182346140658_TIMING.jpg

Jeśli wydaje się, że działa tak, jak chcesz, usuń -n.


5

Możesz także użyć następujących. Najpierw wykonaj kopię zapasową plików i wypróbuj to:

find . -name "*.jpg" -type f -print0| while read -d $'\0' file
do
    #extension="${file##*.}"
    newfilename=$(echo "${file%.*}" | sed 's/\(.*\)_\(.*\)_/\1\2/')
    mv "$file" "$newfilename""_TIMING.jpg"
done

sed 's/\(.*\)_\(.*\)_/\1\2/')usuwa _znaki ze znacznika czasu.

Na przykład:

user@host$ ls -lart
total 8
drwxrwxr-x 6 user user 4096 Oct 21 10:21 ..
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_230014_5335.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_231514_0814.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_233014_5706.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_234514_0896.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_230114_5395.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_231614_1145.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_233114_6047.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_234614_0547.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_230114_5492.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_231614_1264.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_233114_6146.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_234614_0658.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_230214_5630.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_231714_7135.jpg
drwxrwxr-x 2 user user 4096 Oct 21 10:30 .

user@host$ find . -name "*.jpg" -type f -print0 | while read -d $'\0' file
> do
>  newfilename=$(echo "${file%.*}" | sed 's/\(.*\)_\(.*\)_/\1\2/')
>  mv $file $newfilename"_TIMING.jpg"
> done

10:35:20 t $ ls -lart
total 8
drwxrwxr-x 6 user user 4096 Oct 21 10:21 ..
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182300145335_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182315140814_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182330145706_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182345140896_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182301145395_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182316141145_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182331146047_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182346140547_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182301145492_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182316141264_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182331146146_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182346140658_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182302145630_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182317147135_TIMING.jpg
drwxrwxr-x 2 user user 4096 Oct 21 10:35 .

1
to najlepsze rozwiązanie. Oczywiście soulanna Zanna jest idealna dla kilku plików, ale ponieważ globbing jest wykonywany przez powłokę, ich rozwiązanie może zawieść w przypadku dużej liczby plików (zbyt długi ciąg poleceń).
rexkogitans

@rexkogitans: Jeśli korzystasz z nowoczesnego systemu Linux (tj. dowolnej wersji Ubuntu), limit długości wiersza poleceń wynosi wiele megabajtów. A jeśli jest to problem, możesz użyć, find -maxdepth 1 -exec rename ... {} +aby wsadować listę bieżącego katalogu do wiersza polecenia zmiany nazwy. (dodaj -name *.jpglub cokolwiek chcesz). To zadziała znacznie szybciej niż pętla powłoki, która rozwidla + exec sedi mvdla każdej nazwy pliku, zamiast tylko zmiany nazwy wywołania systemowego. (Można się pozbyć sedkorzystania z wbudowanych wyrażeń regularnych basha, ale rozwidlanie mvjest nadal powolne.)
Peter Cordes

2

Prawdopodobnie skończyłeś, ale oto (proste) całe bashrozwiązanie:
Czy „proste ... rozwiązanie bash” jest oksymoronem?

#!/bin/bash

#loop through all files ending in .jpg
for f in *.jpg;
do

    #cut out everything to the timestamp
    firsthalf=${f%_*_*_*}

    #get from the timestamp on
    lasthalf=${f#*_*_}

    #remove (all) underscores from timestamp
    #note the 2 forward slashes...
    lasthalf=${lasthalf//_/}

    #get our extension
    ext=${lasthalf##*.}

    #now we can remove the extension
    lasthalf=${lasthalf%.*}

    #rename the file
    #change `mv` to `echo` if you want to do a trial run first...
    mv "$f" "${firsthalf}_${lasthalf}_TIMING.${ext}"

done;

PS: Logika w pętli została przetestowana z jedną z twoich przykładowych nazw plików. Przeszło.


1
Prawdopodobnie lepiej użyć wyrażenia regularnego z [[ $f ~= (.*)_(.*)_(.*)_(.*)\.jpg ]]; newname=${BASH_REMATCH[1]${BASH_REMATCH:2:4}TIMING.jpgczymś innym . (całkowicie niesprawdzone i prawdopodobnie błędne, ale ogólną ideą jest to, że grupy przechwytywania przechodzą do tablicy BASH_REMATCH.)
Peter Cordes

@PeterCordes: To dobra uwaga! Nigdy nie używałem ( bash) przechwytywania grup, i szczerze mówiąc, bash nie jest pierwszym językiem, w którym chciałbym je wypróbować. (Myślę, że bashto brzydki język.) Mimo to jest to dobre rozwiązanie i nauczyło mnie czegoś tak godnego podziwu.
J. Allan,

Tak, głównym powodem przetwarzania tak dużej ilości tekstu w czystym bashu jest pisanie funkcji uzupełniania tabulatorów, które powinny być szybkie. Nadaje zupełnie nowe znaczenie zwrotowi „brzydki kod” ...
Peter Cordes

@PeterCordes: Rozumiem, o co mi chodzi , choć nie sądzę, że kod jest „brzydki”. Być może nie jest to 2-liniowe rozwiązanie, które podałeś, ale o ile mnie to nie jest trudne; plus jest dobrze skomentowany ...
J. Allan,

Mówiłem o tym, że kod zakończenia bashu jest ogólnie brzydki (lub przynajmniej trudny do odczytania). W rzeczywistości nie jest to naprawdę brzydkie, po prostu nieco oszałamiające (np. Przekazywanie argumentów przez ref w bashu przez przekazanie nazwy zmiennej i użycie przez callee printf -v "$3" ...ustawienia zmiennej, której nazwa jest w nazwie $3). Rozebranie całej linii poleceń i odłożenie jej z powrotem razem jest to dość trudne do śledzenia / debugowania, przynajmniej znalazłem to w ten sposób, próbując to naprawić / naprawić błędy. Zobacz kod na github
Peter Cordes

1

Jeśli możesz użyć GUI, polecam pyRenamer .

Jest obecny w większości dystrybucji, fi w Ubuntu:

sudo apt-get install pyrenamer

Może zrobić wszystko, co chcesz i więcej.

  • Może używać wzorów, dodawać lub pomijać tekst.
  • Może uzyskać dostęp do danych EXIF ​​w przypadku zmiany nazw zdjęć, dzięki czemu można generować wzorce na podstawie daty / godziny itp.
  • Może zmieniać metadane podczas zmiany nazw plików muzycznych.
  • Ponadto ma podgląd , który może zapobiec niektórym błędom trudnym do przywrócenia.

Do downvoter ... Chcesz wyjaśnić, dlaczego? OP nie określił, czy GUI jest opcją, czy nie. Widzę, że większość odpowiedzi dotyczy sposobu konsoli / skryptu, ale wielu użytkowników doceni rozwiązanie GUI. A może pyRenamer ma jakąś wadę, o której nie wiem. W każdym razie lubię znać powody głosów negatywnych.
jrierab

Mogę również zasugerować Thunar Bulk Renamer, aby uzyskać interaktywne GUI.
Tony Martin

@TonyMartin To powinien być komentarz pod znakiem zapytania, nie ma to nic wspólnego z odpowiedzią
Sergiy Kolodyazhnyy

0

Oto Twoje surowe wbudowane find +xargs + sed+ mvoneliner (Love Oneliner):

find . -name "*.jpg" -print0 | sort -z | xargs -0 sh -c 'for filename; do mv "$filename" $(echo "${filename}" | sed "s/\([0-9]\{8\}\)_\([0-9]\{6\}\)_\([0-9]\{4\}\)/\1\2\3_TIMING/g"); done' sh

Wyjaśnienie:

  • find . -name "*.jpg" | sort | xargs sh -c <command> sh : wyświetl listę wszystkich plików JPEG w bieżącym katalogu, a następnie wykonaj polecenie powłoki dla każdego z nich (sortowanie jest oczywiście opcjonalne, ale zachowaj porządek, jeśli gdzieś się logujesz)

  • -print0, -z , -0: To dobry zwyczaj, aby odrębne pozycje z binarnym 0gdy tokenizing nazw plików, aby uniknąć problemów z in-the-middle-białe przestrzenie (choć nie twoja sprawa)

  • mv "$filename" $(echo "${filename}" | sed "s/\([0-9]\{8\}\)_\([0-9]\{6\}\)_\([0-9]\{4\}\)/\1\2\3_TIMING/g");: (odwrotne ukośniki w sedwyrażeniu regularnym nie pomagają w jego czytelności, ale jest to proste) zmień nazwę każdego pliku, zastępując sekwencję podkreśloną 8 + 6 + 4 cyfr ich ciągłą konkatenacją plus to _TIMINGcoś (\i jest to odwołanie do i- grupa wyrażeń regularnych).


Refs: Xargs - mężczyzna sed

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.