Come rinominare in batch i file in un terminale macOS?


123

Ho una cartella con una serie di file denominati:

prefix_1234_567.png
prefix_abcd_efg.png

Vorrei rimuovere in batch un trattino basso e il contenuto centrale in modo che l'output sarebbe:

prefix_567.png
prefix_efg.png

Rilevante ma non completamente esplicativo:


guarda i metodi di gamma e sottostringa di NSString e NSMutableString
Grady Player

1
Hai considerato soluzioni non terminali a questo? Un flusso di lavoro di Automator può eseguire questi tipi di operazioni con facilità. È possibile creare un flusso di lavoro di automator per rinominare tutti i file e sostituire il testo _*_con uno spazio vuoto.
Encryptic

Pensavo che l'automator non potesse fare i caratteri jolly
rapito l'

Risposte:


234

Nel tuo caso specifico puoi usare il seguente bashcomando ( bashè la shell predefinita su macOS):

for f in *.png; do echo mv "$f" "${f/_*_/_}"; done

Nota: se è possibile che i nomi dei file inizino con -, inseriscili -- prima [1]:
mv -- "$f" "${f/_*_/_}"

Nota: echoè anteposto a in mvmodo da eseguire una marcia a secco. Rimuoverlo per eseguire la ridenominazione effettiva.

Puoi eseguirlo dalla riga di comando o usarlo in uno script.

  • "${f/_*_/_}"è un'applicazione bash dell'espansione dei parametri : il (primo) pattern di corrispondenza della sottostringa _*_viene sostituito con letterale _, tagliando effettivamente il token centrale dal nome.
  • Si noti che _*_è un pattern (un'espressione jolly, utilizzata anche per il globbing), non un'espressione regolare (per conoscere i pattern, eseguire man bashe cercare Pattern Matching).

Se ti accorgi di rinominare i file frequentemente, considera l'installazione di uno strumento specializzato come l' renameutilità basata su Perl . Su macOS puoi installarlo utilizzando il popolare gestore di pacchetti Homebrew come segue:

brew install rename

Ecco l'equivalente del comando in alto usando rename:

rename -n -e 's/_.*_/_/'  *.png

Anche in questo caso, questo comando esegue un funzionamento a secco; rimuovere -nper eseguire la ridenominazione effettiva.

  • Simile alla bashsoluzione, s/.../.../esegue la sostituzione del testo, ma - a differenza di bash- vengono utilizzate espressioni regolari vere .

[1] Lo scopo della speciale argomento --, che è supportato dalla maggior parte dei programmi di utilità, è da segnalare che argomenti successivi devono essere trattati come operandi (valori), anche se sembrano come opzioni causa iniziano -, come Jacob C. note.


3
ottima risposta, ha funzionato perfettamente. Apprezzo anche che tu sia tornato indietro e lo abbia modificato per spiegarlo di più e fornire una soluzione più elegante se lo ripeto. ancora una volta, molte grazie, molto disponibile
rapito l'

4
Un esempio che utilizza sostituzioni corrispondenti ( .*-> $1), ad esempio Rinomina Foo bar S01E01 biz baz.extin S01E01.ext:rename -n -e 's/.*(S[0-9]{2}E[0-9]{2}).*(\.[a-z]{2,4})/$1$2/' *
Steve Robbins

2
Adoro l'idea di utilizzare echoper le corse a secco. Grazie per il consiglio!
James Wright

Consiglio vivamente di fare ilbrew install rename
Chris Redford il

98

Per rinominare i file, puoi utilizzare l' renameutilità:

brew install rename

Ad esempio, per modificare una stringa di ricerca in tutti i nomi di file nella directory corrente:

rename -nvs searchword replaceword *

Rimuovere il parametro "n" per applicare le modifiche.

Ulteriori informazioni: man rename


1
OS Xle versioni di GNU bash( x86_64-apple-darwin ) non includono l'utilità di ridenominazione.
l'L'l

4
Grazie, sì, deve essere installato tramitebrew install rename
David Thomas

2
Questo suggerimento è fantastico! Ho digitato rename -vs GLYCOPHORIN GLYCC *e ora rinomina automaticamente oltre 450 file. E anche super veloce.
Sander W. van der Laan

3
Eccellente! Adoro la parte "mostra cosa sarebbe cambiato" PRIMA che rinomina effettivamente le cose!
Ben Duffin

3
Puoi anche usare un'espressione regolare. rinomina 's / 123 / onetwothree / g' *
Bryan

12

Potresti usare sed:

ls * | sed -e 'p;s@_.*_@_@g' | xargs -n2 mv

risultato:

prefix_567.png prefix_efg.png

* per eseguire prima una prova a secco, sostituire mvalla fine conecho

Spiegazione:

  • e: opzionale solo per 1 comando sed.
  • p: per stampare l'input su sed, in questo caso sarà il nome del file originale prima di qualsiasi ridenominazione
  • @: è una sostituzione del carattere / per rendere sed più leggibile. Cioè, invece di usare sed s / search / replace / g, usa s @ search @ replace @ g
  • _. *: il carattere di sottolineatura è un carattere di escape per fare riferimento al carattere "." carattere zero o più volte (al contrario di QUALSIASI carattere in regex)
  • -n2: indica che ci sono 2 uscite che devono essere passate a mv come parametri. per ogni input da ls , questo comando sed genererà 2 output, che verranno poi forniti a mv.

1
Soluzione intelligente, anche se un po 'arcana. Rendendolo più generale, in modo da supportare anche nomi di file con spazi incorporati, diventa ancora più arcano: ls * | xargs -I % bash -c 'echo mv "%" "$(sed 's@_.*_@_@' <<<"%")"'(rimuovere echoper rinominare effettivamente).
mklement0

2
Arcano? Amo questo!
Bilal Akil

7

Avevo una serie di file che assomigliavano a questo: be90-01.png e dovevo cambiare il trattino in sottolineatura. Ho usato questo, che ha funzionato bene:

for f in *; do mv "$f" "`echo $f | tr '-' '_'`"; done

2

puoi installare il renamecomando usando brew. fallo brew install renamee usalo.


1

utilizzando mmv

mmv '*_*_*' '#1_#3' *.png

devi prima installare sudo apt-get install mmv.
αғsнιη

1
Dato che si trattava di OS X, la procedura di installazione corretta è brew install mmv.
buckaroo1177125

1

prova questo

for i in *.png ; do mv "$i" "${i/remove_me*.png/.png}" ; done

Ecco un altro modo:

for file in Name*.png; do mv "$file" "01_$file"; done
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.