Esiste un comando linux come mv ma con regex?


Risposte:


32

Come altri hanno già detto, renameè bravo in questo, ma leggi la pagina man ( man rename) prima di provarlo. Ci sono almeno due strumenti completamente diversi là fuori chiamati renamee quale possiedi dipenderà dalla tua distribuzione. Chiamarli in modo errato può essere pericoloso.

Ecco la pagina man per la versione basata su perl di Larry Wall fornita con Ubuntu. Gli dai un'espressione perl comerename 's/\.sql$/.php/' *.sql

Ecco la pagina man per la ridenominazione fornita con le versioni precedenti di Red Hat e CentOS. L'utilizzo è semplice sostituzione della stringa comerename .sql .php *.sql

Puoi anche usare un bash one-liner per elaborare ogni file uno alla volta:

$ for f in *.sql; do mv -i "$f" "${f%%.*}.php"; done

Qualcuno potrebbe caricare un file binario di Windows per la ridenominazione basata su perl?
mcandre,

La ridenominazione della versione Perl non può spostare i file da un file system a un altro.
lilydjwg,

bash one-liner è utile, soprattutto quando non si ha alcuna renamefunzione (es. busybox)
artm

10

Ecco rename(1), che non usa regex, ma può risolvere il tuo problema:

rename .sql .php *.sql

C'è anche mmv(1), ma non ho familiarità con come funziona.


In Ubuntu e Debian (non sono sicuro di altre distribuzioni), si /usr/bin/renamecollega per /usr/bin/prenameimpostazione predefinita, che richiede regexps.
ℝaphink,

5

Buongiorno,

Potresti anche provare a entrare

for i in $(\ls -d *.sql)
do
mv $i $(echo $i | sed -e 's/\.sql$/\.php/')
done

O per farlo usa regex cambiandolo leggermente in

for i in $(\ls -d | egrep -e '.*\.sql')
do
mv $i $(echo $i | sed -e 's/\.sql$/\.php/')
done

per un po 'di divertimento nella codifica della shell. (-:


2
Questo non riesce con i file che contengono spazi bianchi nel loro nome, quindi fai attenzione. Non si dovrebbe mai analizzare l' lsoutput .
slhck,

L' sedesempio è abbastanza buono, però.
stella luminosa l'

2

Essendo un idraulico, mi piacciono le pipe :)

Nota: questa risposta è dettagliata - come newbee la apprezzo quando qualcuno che conosce si prende il tempo di spiegare, quindi sto pagando "in avanti". Se non sei un novizio, scusa la lunghezza e la verbosità.

ls -1 *_201[67][0-9]* | sed -e 's/\(\(.\+\)[-_]\(201[67][0-9]\{4\}\)\([^.]\+\)\?\.[0-9a-z]\{2,3\}\)/mkdir -p \2\/\3; mv \1 \2\/\3\/\1/' | bash

Dove:

ls -1 *_201[67][0-9]*

elenca tutti i file che corrispondono al modello, in questo caso sto cercando i file con la data nel nome del file nel modulo "AAAAMMGG"

sed -e 's/\(\(.\+\)[-_]\(201[67][0-9]\{4\}\)\([^.]\+\)\?\.[0-9a-z]\{2,3\}\)/mkdir -p \2\/\3; mv \1 \2\/\3\/\1/'
#        : | |    |     |                  | |       |                    |:                                 :
#        : |^2....^    ^3..................^^4.......^                    |:                                 :
#        :^1..............................................................^:                                 :
#        /................filename.................pattern................./...mkdir...and....mv...command.../

^ 1: 1 ° gruppo di acquisizione - l'intero nome del file

^ 2: 2 ° gruppo di acquisizione: la prima parte del modello di nome file

^ 3: 3 ° gruppo di acquisizione - la seconda parte del nome file - qui, la data come 'AAAAMMGG'

^ 4: 4 ° gruppo di acquisizione: parte del nome file facoltativa tra la data e l'estensione e l'estensione stessa

Sooooo .... se ho un file chiamato

CallLog_555123412_20161231-214403.7z

...poi

mkdir -p \2\/\3; mv \1 \2\/\3\/\1

in realtà significa

# make directory and sub-directory
mkdir -p CallLog_555123412/20161231
# move file from current directory to sub-sub-directory just created
mv CallLog_555123412_20161231-214403.7z CallLog_555123412/20161231/CallLog_555123412_20161231-214403.7z

Si noti che l'output del comando sed viene reindirizzato a 'bash' per eseguirlo. Per vedere prima gli spostamenti dei file proposti SENZA effettivamente spostarli, rimuovere prima '| bash 'alla fine, e provalo così:

ls -1 *_201[67][0-9]* | sed -e 's/\(\(.\+\)[-_]\(201[67][0-9]\{4\}\)\([^.]\+\)\?\.[0-9a-z]\{2,3\}\)/mkdir -p \2\/\3; mv \1 \2\/\3\/\1/'

Questo non farà alcun cambiamento, ma vedrai il comando che verrà eseguito SE lo esegui con '| bash 'taggato alla fine.

Questo è utile perché puoi creare qualsiasi sottodirectory che desideri dalle parti nel nome del file o qualsiasi altra cosa che aggiungi al testo 'sostituzione' nel comando sed. Nota che sed richiede molti personaggi di escape, però.

Staffe SED Regex:

(...) richiede l'escaping per il raggruppamento delle acquisizioni -> \ (... \)

{m, n} richiede l'escaping per quantificare l'oggetto precedente -> \ {m, n \}

/ richiede l'escaping nella stringa di sostituzione -> \ /

[...] NON è necessario scappare per le classi di caratteri

\ 1 nella stringa di sostituzione si riferisce al 1 ° gruppo acquisito e così via ...

AVVISO DI SICUREZZA: MAI TUBARE QUALCOSA PER 'colpire' A MENO CHE NON COMPRENDI COMPLETAMENTE IL RISULTATO ...

Spero che aiuti a eliminare alcuni blocchi :)


1

Installa mmv, quindi fai questo:

mmv "*.sql" "#1.php"
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.