Come rinominare più file in una directory contemporaneamente


12

Ho directory dire /var/tmp/abcche ha 4 file:

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

Voglio rinominare tutti i file CSV (trovare tutti i file e rinominarli) nel modo più breve possibile (probabilmente con una riga) in questo modo:

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

Risposte:


15

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

rimuovere il -nquando felice.


2
Per una versione adatta di rename. Presumo che questo sia Larry Wall rename, dal renamepacchetto in Debian e derivati ​​(e IIRC prenamesui sistemi di persuasione RedHat). Uno strumento molto utile
Xenoid,

2
perl-renamein arch linux
lesmana

1
@SHawarden, ho provato ad eseguire il comando e leggere la parte pertinente della pagina man per capire il modello di sostituzione, ma quando si aggiunge il verboseflag, non viene emesso nulla e non si eseguono le modifiche al nome del file, anche se il percorso corrente ha file con nomi simili a 12345_foo.csv. Devo svolgere qualche attività aggiuntiva per farlo funzionare (attualmente su Fedora 30)? È un approccio più pulito del looping. Grazie in anticipo!
danieldeveloper001,

3
@ danieldeveloper001 Hai usato renameo prename? Vedi il mio commento sopra. man {the command}elenca gli autori alla fine.
xenoide,

2
Funziona solo su sistemi derivati ​​da Debian. I sistemi derivati ​​da Fedora hanno un renamecomando completamente diverso ; vedi unix.stackexchange.com/a/238862/135943
Wildcard

11

Provare:

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

Come funziona:

  • for f in *.csv; do

    Questo avvia un ciclo su tutti i *.csvfile.

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

    Ciò rinomina i file come desiderato, chiedendo in modo interattivo prima di sovrascrivere qualsiasi file.

  • done

    Questo segna la fine del ciclo.

Esempio:

$ 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

Mi è piaciuta la piccola sfida che hai pubblicato, quindi ecco la mia soluzione. Suppongo che tutti i tuoi file inizino con 5 caratteri numerici, quindi usando il comando cut per sostituire i file numerici iniziali con "XXXXX".

Di seguito, i file prima del comando.

-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

Sotto, il comando one liner.

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

Di seguito, i file dopo il comando.

-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

È quello che stai cercando? :)

Riferimenti:

Riproduzione ciclica dell'output del comando in bash

Sottostringa in bash


2
Bash può fare questo tipo di manipolazione delle stringhe, non è necessario eseguire un fork di un nuovo processo per ciascuno, per favore, l'altra risposta su come.
chx

1
@chx, ho già visto le altre risposte e ne ho acquisito un po 'di conoscenza, ma grazie per averle segnalate. Potresti approfondire per favore no need to fork a new process for each?
danieldeveloper001,

3
cutè un binario separato ( /usr/bin/cut) e in esecuzione consuma più risorse rispetto all'utilizzo di shell incorporate.
chx,

2
Vedo, in realtà è importante se l'intento sta rinominando molti file. Grazie per il chiarimento!
danieldeveloper001,

1

senza forcelle:

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

Quando si utilizza un loop shell, le mvforchette una volta per file. Il renamecomando di Perl no.

(Il comando di rinomina di Perl ha alcune restrizioni, ma in questo caso specifico quelle restrizioni non si applicano.)

Per quanto riguarda il renamecomando mostrato in precedenza, sì, funziona, ma poi hai tutta quella confusione tra due diversi tipi di rinomina e così via. Se hai quello giusto, fantastico, ma in caso contrario, funziona anche questo.

Se non si dispone del comando perl-rename e non è possibile installarlo, è possibile:

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

Come puoi vedere, utilizza la stessa sostituzione mostrata nella risposta in alto. Naturalmente il perl-rename ha altre campane e fischietti (la risposta in alto accennato, -ngià, poi c'è -0, -fe così via), e più di loro è necessario, tanto più è necessario installare che invece di rotazione proprio in questo modo .


Le solite implementazioni di una pipe avranno forcelle.
Muru,

Volevo dire "non verrà fork una volta per ogni file da rinominare", diversamente dalla shell, dove "mv" forchette / usr / bin / mv o altro. Questo perché il comando "rename" è un comando interno perl che chiama direttamente rename () in libc. Naturalmente ha alcune restrizioni, ma in questo esempio specifico quelle restrizioni non si applicano.
sitaram,

1
Questo è vero anche per il renamecomando (la risposta in alto , usa anche Perl), quindi forse dovresti aggiungere alla spiegazione un po 'più di spiegazioni che semplicemente "niente forchette".
muru,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.