2011-12-07 2 views
39

C'è una scorciatoia in Shell/Bash che può rinominare tutti i file in una cartella in base a un'espressione regolare o ad altri criteri. Quello che sto cercando qui è nella cartella Documenti, che ha diciamo un file di testo 100 con la seguente convenzione di denominazione:Scorciatoia shell/Bash per rinominare in blocco i file in una cartella

<longdocumentidentifier>-doc-<counter>.txt. 

ho bisogno di rinominare tutti i file con il sopra data convenzione a poco:

doc-<counter>.txt 

C'è un one-liner che può aiutarmi con quanto sopra?

risposta

76

Vorrei suggerire qualcosa di simile:

for i in *-doc-*.txt; do mv $i ${i/*-doc-/doc-}; done 

${i/*-doc-/doc-} sostituisce la prima occorrenza di *-doc- con doc-.

Se è necessario eseguire più di una sostituzione (vedere il commento numero 1), è necessario utilizzare la variante ${var//Pattern/Replacement}. Se è necessario sostituire l'inizio del nome è necessario utilizzare , se è necessario sostituire la fine (es .: l'estensione) è necessario utilizzare il modulo ${var/%Pattern/Replacement}.

Vedere http://tldp.org/LDP/abs/html/parameter-substitution.html#EXPREPL1 per maggiori dettagli

+2

Questo è stato utile per un caso leggermente diverso; dove volevo sostituire tutti gli spazi in alcuni nomi di file con trattini: 'for i in *; fai mv "$ i" $ {i // \/-}; done'. Si noti che per fare questo ho dovuto citare i nomi dei file originali. –

+0

L'ho usato per rimuovere .sh da tutti i nomi degli script :-) 'for i in * .sh; fai mv $ i $ {i/.sh /}; done'. – erm3nda

+0

@ erm3nda fai attenzione: '$ {i/.sh /}' cancella la prima corrispondenza della stringa .sh. Per assicurarti di rimuovere l'estensione (che presumo tu voglia) dovresti usare '$ {i /%. Sh /}' – Sorin

8

Il comando di rinomina incorporato nella maggior parte di Linux, ad esempio, lo farà facilmente.

Personalmente, preferisco espressioni regolari troppo che è il motivo per cui mi sono portata in giro questo script per un tempo molto molto molto lungo (leggi: dal fine degli anni '80 o primi anni '90):

#!/usr/bin/perl 

($op = shift) || die "Usage: $0 expr [files]]\n"; 

if([email protected]) 
    { 
    @ARGV = <STDIN>; 
    chop(@ARGV); 
    } 

for (@ARGV) 
    { 
    $was = $_; 
    eval $op; 
    die [email protected] if [email protected]; 

    if ($was ne $_) 
    { 
    print "rename($was,$_)\n"; 
    rename($was,$_); 
    } 
    } 

che, installato permette di fare cose come questa:

script-name 's/.*-doc(.*).txt/doc$1.txt/' *.txt 
12

C'è prename, che consente di utilizzare REGEX:

prename 's/^.*-doc-(.*\.txt)$/doc-$1/' *.txt 

Utilizzare l'opzione -n simulare:

prename -n 's/^.*-doc-(.*\.txt)$/doc-$1/' *.txt 

Nota: Questo è spedito come rename in molte distribuzioni Linux, ma non in tutti, quindi sto usando il nome canonico per l'utilità fornita con Perl.

+4

downvoter: cura di commentare? – elias

18

Se si dispone di rename quindi, rename 's/^.*-doc-/doc-/' *.txt dovrebbe fare il trucco.

3
mmv "*-doc-*" "doc-#2" 

comando MMV sta per "mossa di massa"

5

Se si desidera recurse in sotto-directory, v'è anche:

find . -maxdepth N -type f -name "$pattern" | sed -e 'p' -E -e "s/$str1/$str2/g" | xargs -n2 mv 

Sul sistema che automaticamente il supporto Le espressioni regolari estese, si può lasciare lo -E.

Vantaggi:

  • recurses in sotto-directory
  • è possibile controllare la maxdepth della ricorsione
  • è possibile rinominare i file e/o directory (tipo f | d)

Svantaggi:

  • lieve y espressioni regolari più complicate, perché devi mettere a nudo fuori il percorso per arrivare al nome del file

(risposta modificato da here)

3

Se non ti dispiace strumento esterno, allora ecco una: rnm (web page)

per il vostro problema particolare, il comando sarà:

rnm -rs '/.*-doc-/doc-/' *.txt 

O

0.123.
rnm -rs '/.*-(doc-.*\.txt)/\1/' *.txt 

Puoi trovare altri esempi/documenti here.

0

trovare. -name '* scss' | xargs -L1 -I {} echo {} {} | sed 's/css.scss $/scss /' | xargs -L1 mv

per esempio se si dispone di un gruppo di file che terminano con ".css.scss" e che si desidera rinominare loro di terminare con semplicemente ".scss" (cioè rimuovere la parte css)

tweak il regexp e trova argomenti alle vostre esigenze