Zmień nazwy wielu plików za pomocą skryptów Bash

Chcę zmienić nazwy wielu plików w tym samym katalogu za pomocą skryptów Bash. Nazwy plików są następujące:

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

Chcę zmienić nazwę na następujący format:

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

Czytałem o poleceniu rename i próbowałem to zrobić w ten sposób, ale nic nie robi, myślę, że mam pytania dotyczące składni. Następnie przeczytałem, że możesz utworzyć pętlę za pomocą polecenia mv w następujący sposób:

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

Ale nie mogę zmienić nazw plików. Co robię źle?

Komentarze

  • możliwy duplikat Jak mogę dużo zmienić nazwę plików używając wyrażenia regularnego?
  • Możesz ' t mieć wyrażenie wzorcowe po prawej stronie wyrażenia zastępującego rozwijanie parametrów. Czego spodziewałeś się tam, gdzie * jest?
  • @Kiwy To pytanie dotyczy usunięcia części nazwy pliku. Ergo, bardzo wątpliwe powielenie.
  • Następnym razem opisz proszę zmiany w nazwie pliku, które chcesz wprowadzić (musiałem się temu przyjrzeć przez chwilę, zanim zobaczyłem różnice i podobieństwa). Przykłady są dobre, ale opis oraz przykłady jest jeszcze lepszy.

Odpowiedź

Miałeś rację, rozważając najpierw zmianę nazwy. Składnia jest trochę dziwna, jeśli nie jesteś przyzwyczajony do wyrażeń regularnych, ale jest to zdecydowanie najszybsza / najkrótsza droga, gdy wiesz, co robisz:

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

To po prostu dopasowuje pierwsze 4 cyfry i zamienia je na te, które podałeś.

I testowa wiązka przewodów (-vn oznacza być rozwlekłą, ale nie „t rób cokolwiek) używając nazw plików:

$ 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 

Komentarze

  • Uwaga że jest to zmiana nazwy Perla na Debianie i pochodnych (Ubuntu, Mint,…). W innych dystrybucjach Linuksa rename to zupełnie inne narzędzie do zmiany nazw plików (które Debian jest dostarczany jako rename.ul).
  • Jeśli twój dystrybucyjny brak takiego narzędzia, spójrz na odpowiedź @Michael Campbell. Myślę, że każda dystrybucja zastąpi domyślną rename tak jak zrobił to debian.

Odpowiedź

To powinno załatwić sprawę:

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

Zastępuje ciąg między 4. a 12. znakiem „25032014”.

Komentarze

  • to for f in file*; do mv $f ${f/${f:4:4}/2503}; done też działa.
  • That ' jest fajne. Jeśli chcesz użyć zwykłego słowa do zamiany słów, działa to jak sed. na przykład for f in *Huge*; do mv $f ${f/Huge/Monstrous}; done
  • @Eric – opublikowałem Twoją odpowiedź jako alternatywę, ponieważ myślę, że jest ona ' bardziej przejrzysta i elegancka . Jeśli chcesz również opublikować to jako odpowiedź – ' skasuję swoją. Dzięki!
  • Dlaczego brakuje podwójnych cudzysłowów ?
  • Występuje błąd: " mv: target ' FILE_NAME ' nie jest katalogiem "

Odpowiedź

to jest naprawdę odpowiedź @Erica z góry – ale to elegancka odpowiedź, więc Publikuję ponownie jako właściwą odpowiedź, aby zwrócić na nią więcej uwagi.

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

Odpowiedź

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 ) 

To powinno załatwić sprawę. Uwaga – nie mam w zwyczaju przekazywać poleceń masowych mv – jak napisano, to tylko echo. Ty” Muszę to rozwiązać, zanim to zadziała.

Odpowiedź

Prosty natywny sposób na zrobienie tego bez zapętlania, z przeglądanie katalogu :

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

Będzie zmieniać nazwę co plik na miejscu.

A poniżej praca przykład z zrównolegleniem :

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

Komentarze

  • Łatwo było wyobrazić sobie lepsze rozwiązanie. Jeśli chcesz, aby działało polecenie:
  • find -type f -name "file*.p" | parallel 'ext="{}" ; mv -- {} ${ext:0:4}2503${ext:8}'

Odpowiedz

Jeśli zauważysz, że często robisz takie rzeczy, wyszukaj „rename.pl”. Jest to skrypt w Perlu, ale pozwala po prostu przesłać go kodem Perla (jak /// wyrażenie) i dokona masowej zmiany nazwy na podstawie tego wyrażenia lub kodu.

Istnieje wersja podstawowa tutaj: http://stackoverflow.org/wiki/Rename.pl , ale po sieci krążą inne wersje. To istnieje od wieków, od wieków i od wieków.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *