Jak zmienić nazwę wielu plików w katalogu jednocześnie


12

Mam katalog powiedzieć, /var/tmp/abcktóry ma 4 pliki:

12345-ram-3e3r5-io9490-89adu9.csv
45434-dam-qwe35-to9490-43adu9.csv
11234-cam-yy3r5-ro9490-85adu9.csv
14423-sam-hh3r5-uo9490-869du9.csv

Chcę zmienić nazwę wszystkich plików CSV (znaleźć wszystkie pliki i zmienić ich nazwę) w najkrótszym możliwym (prawdopodobnie jednopoziomowym) sposobie:

XXXXX-ram-3e3r5-io9490-89adu9.csv
XXXXX-dam-qwe35-to9490-43adu9.csv
XXXXX-cam-yy3r5-ro9490-85adu9.csv
XXXXX-sam-hh3r5-uo9490-869du9.csv

Odpowiedzi:


15

rename -n 's/(\w+)/XXXXX/' *.csv

usuń -nkiedy szczęśliwy.


2
Dla odpowiedniej wersji rename. Zakładam, że jest to Larry Wall renamez renamepakietu Debiana i pochodnych (i IIRC prenamena systemach perswazji RedHata). Bardzo przydatne narzędzie.
ksenoid

2
perl-renamew arch linux
lesmana

1
@Hawarden, próbowałem wykonać polecenie i przeczytać odpowiednią część strony podręcznika, aby zrozumieć wzorzec zastępowania, ale podczas dodawania verboseflagi nic nie wyświetla i nie wykonuje zmian nazw plików, mimo że bieżąca ścieżka ma pliki o nazwach podobnych do 12345_foo.csv. Czy muszę wykonać jakieś dodatkowe zadanie, aby działało (obecnie na Fedorze 30)? Jest to czystsze podejście niż zapętlenie. Z góry dziękuję!
danieldeveloper001

3
@ danieldeveloper001 Czy używałeś renamelub prename? Zobacz mój komentarz powyżej. man {the command}wymienia autorów na końcu.
ksenoid

2
Działa to tylko w systemach opartych na Debianie. Systemy pochodzące z Fedory mają zupełnie inne renamepolecenie; patrz unix.stackexchange.com/a/238862/135943
Wildcard

11

Próbować:

for f in *.csv; do mv -i -- "$f" "XXXXX-${f#*-}"; done

Jak to działa:

  • for f in *.csv; do

    To uruchamia pętlę nad wszystkimi *.csvplikami.

  • mv -i -- "$f" "XXXXX-${f#*-}"

    Spowoduje to zmianę nazw plików zgodnie z potrzebami, pytając interaktywnie przed zastąpieniem dowolnego pliku.

  • done

    To oznacza koniec pętli.

Przykład:

$ ls -1
11234-cam-yy3r5-ro9490-85adu9.csv
12345-ram-3e3r5-io9490-89adu9.csv
14423-sam-hh3r5-uo9490-869du9.csv
45434-dam-qwe35-to9490-43adu9.csv
$ for f in *.csv; do mv -i -- "$f" "XXXXX-${f#*-}"; done
$ ls -1
XXXXX-cam-yy3r5-ro9490-85adu9.csv
XXXXX-dam-qwe35-to9490-43adu9.csv
XXXXX-ram-3e3r5-io9490-89adu9.csv
XXXXX-sam-hh3r5-uo9490-869du9.csv

4

Podobało mi się małe wyzwanie, które wysłałeś, więc oto moje rozwiązanie. Zakładam, że wszystkie twoje pliki zaczynają się od 5 znaków numerycznych, więc użyj polecenia cut, aby zamienić początkowe pliki numeryczne na „XXXXX”.

Poniżej pliki przed poleceniem.

-rw-rw-r--. 1 daniel daniel 0 May 13 23:18 11111_bar_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 12345_baz_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 67890_foo_file.xml

Poniżej jedno polecenie liniowej.

for src in *.csv; do dst=XXXXX$(echo $src| cut -c6-); mv $src $dst; done;

Poniżej pliki po poleceniu.

-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 67890_foo_file.xml
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 XXXXX_bar_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 23:18 XXXXX_baz_file.csv

Czy tego szukasz? :)

Bibliografia:

Zapętlanie danych wyjściowych poleceń w bash

Podciągi w bash


2
Bash może wykonywać tego rodzaju manipulacje ciągami, nie trzeba rozwidlać nowego procesu dla każdego, proszę o drugą odpowiedź, w jaki sposób.
chx

1
@chx, widziałem już inne odpowiedzi i zdobyłem z tego trochę wiedzy, ale dziękuję za wskazanie ich. Czy mógłbyś rozwinąć tę kwestię no need to fork a new process for each?
danieldeveloper001

3
cutjest osobnym plikiem binarnym ( /usr/bin/cut), a jego uruchomienie zużywa więcej zasobów niż używanie wbudowanych poleceń powłoki.
chx

2
Rozumiem, właściwie to ma znaczenie, jeśli zamiar zmienia nazwę wielu plików. Dziękuję za wyjaśnienie!
danieldeveloper001

1

bez widelców:

ls | perl -lne '$suf=substr($_,6); rename $_, "XXXXX-$suf"'

Gdy używasz pętli powłoki, mvforks raz na plik. renamePolecenie Perla nie.

(Polecenie Perla dotyczące zmiany nazwy ma pewne ograniczenia, ale w tym konkretnym przypadku ograniczenia te nie mają zastosowania.)

Jeśli chodzi o renamepolecenie pokazane wcześniej, tak, to działa, ale wtedy masz całe zamieszanie między dwoma różnymi rodzajami zmiany nazwy i tak dalej. Jeśli masz odpowiedni, świetnie, ale jeśli nie, to też działa.

Jeśli nie masz polecenia perl-rename i nie możesz go zainstalować, możesz po prostu to zrobić:

ls | perl -lne '$old=$_; s/(\w+)/XXXXX/; rename $old, $_'

Jak widać, używa tego samego podstawienia pokazanego w górnej odpowiedzi. Oczywiście, nazwa-perl ma inne dzwonki i gwizdki (wspomniana najlepsza odpowiedź, -njuż tam jest -0, -fitd.), A im więcej ich potrzebujesz, tym więcej powinieneś zainstalować, zamiast wymieniać własne w ten sposób .


Zwykłe implementacje rury będą miały widelce.
muru

Miałem na myśli: „nie rozwidli się raz na plik do zmiany nazwy”, w przeciwieństwie nawet do powłoki, gdzie „mv” rozwidla / usr / bin / mv lub cokolwiek innego. Wynika to z faktu, że polecenie „rename” to wewnętrzne polecenie perla, które bezpośrednio wywołuje rename () w libc. Oczywiście ma pewne ograniczenia, ale w tym konkretnym przykładzie ograniczenia te nie mają zastosowania.
sitaram

1
Dotyczy to również renamepolecenia ( najwyższa odpowiedź , również używa Perla), więc może powinieneś dodać nieco więcej wyjaśnień niż po prostu „brak widelców” w odpowiedzi.
muru
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.