Come rimuovere i caratteri non validi dai nomi dei file?


47

Ho file con caratteri non validi come questi

009_-_�%86ndringshåndtering.html

È un punto in Æcui qualcosa è andato storto nel nome del file.

C'è un modo per rimuovere solo tutti i caratteri non validi?

o potrebbe tressere usato in qualche modo?

echo "009_-_�%86ndringshåndtering.html" | tr ???

5
I personaggi probabilmente non sono "invalidi", altrimenti il ​​filesystem non li memorizzerebbe (a meno che tu non abbia fatto qualcosa di veramente brutto su FS). Hai provato a modificare le impostazioni internazionali (ad esempio UTF8) per visualizzare correttamente i nomi?
James O'Gorman,

Risposte:


41

Un modo sarebbe con sed:

mv 'file' $(echo 'file' | sed -e 's/[^A-Za-z0-9._-]/_/g')

Sostituisci filecon il tuo nome file, ovviamente. Questo sostituirà tutto ciò che non è una lettera, un numero, un punto, un trattino basso o un trattino con un trattino basso. Puoi aggiungere o rimuovere caratteri per mantenerli come preferisci e / o cambiare il carattere sostitutivo in qualsiasi altra cosa o in nessun altro.


4
Ho usato:f='file'; mv 'file' ${f//[^A-Za-z0-9._-]/_}
Louis il

1
Cerca la migliore soluzione di H. Hess in basso ... (e il mio commento divertente a fianco :))
Jan Sila,

31

Presumo che tu sia su Linux box e che i file siano stati creati su Windows box. Linux usa UTF-8 come codifica dei caratteri per i nomi dei file, mentre Windows usa qualcos'altro. Penso che questa sia la causa del problema.

Vorrei usare "convmv". Questo è uno strumento che può convertire i nomi di file da una codifica di caratteri a un'altra. Per l'Europa occidentale uno di questi funziona normalmente:

convmv -r -f windows-1252 -t UTF-8 .
convmv -r -f ISO-8859-1 -t UTF-8 .
convmv -r -f cp-850 -t UTF-8 .

Se è necessario installarlo su un Linux basato su Debian, è possibile farlo eseguendo:

sudo apt-get install convmv

Funziona sempre per me e recupera il nome file originale.

Fonte: LeaseWebLabs


1
questo sembra promettente, ma hai idea di come dire quale sia la codifica? Ho una directory chiamata Save the current file in Word 97-2004 format\sco.workflowche è stata creata sul mio Mac (tramite Microsoft Office) e le codifiche sopra riportate non hanno alcun effetto.
Sridhar Sarnobat,

Vale la pena sottolineare che per impostazione predefinita convmv viene eseguito in modalità "test", dove esegue solo una prova a secco e ti dice quali file si sposterà. Ti dirà quindi di eseguirlo nuovamente con l' --notestopzione per rinominare effettivamente i file.
Kenny Rasschaert,

16

Suppongo che vuoi dire che vuoi attraversare il filesystem e sistemare tutti questi file?

Ecco come lo farei

find /path/to/files -type f -print0 | \
perl -n0e '$new = $_; if($new =~ s/[^[:ascii:]]/_/g) {
  print("Renaming $_ to $new\n"); rename($_, $new);
}'

Ciò troverebbe tutti i file con caratteri non ASCII e sostituirà quei caratteri con caratteri di sottolineatura ( _). Fai attenzione, tuttavia, se esiste già un file con il nuovo nome, lo sovrascriverà. Lo script può essere modificato per verificare un caso del genere, ma non l'ho inserito per renderlo semplice.


13

Seguendo le risposte a https://stackoverflow.com/questions/2124010/grep-regex-to-match-non-ascii-characters , è possibile utilizzare:

rename 's/[^\x00-\x7F]//g' *

dove *corrisponde ai file che si desidera rinominare. Se vuoi farlo su più directory, puoi fare qualcosa del tipo:

find . -exec rename 's/[^\x00-\x7F]//g' "{}" \;

Puoi usare l'argomento -n renameper fare una corsa a secco e vedere cosa sarebbe cambiato, senza cambiarlo.


C'è un modo per modificarlo per mantenere caratteri stranieri come ü e ä per esempio?
Elder Geek,

Solo il secondo ha funzionato per me. Tutto era nella stessa directory, quindi non sono sicuro di quale sia la differenza ..?
Shautieh,

1
@Shautieh: -n interrompe la sua esecuzione effettiva. Chiarirò la risposta.
niente101

la ridenominazione può essere lenta quando si ha a che fare con molti file. Se si desidera accelerare questo, spingere il segno di spunta per trovare. Non sono sicuro di come farlo però.
Isaaclw,

13

Ho avuto alcuni file giapponesi con nomi di file rotti recuperati da una chiavetta USB rotta e le soluzioni sopra non hanno funzionato per me.

Raccomando il pacchetto di disintossicazione:

L'utility detox rinomina i file per facilitarne il funzionamento. Rimuove gli spazi e altri fastidi simili. Tradurrà o pulirà anche i caratteri Latin-1 (ISO 8859-1) codificati in ASCII a 8 bit, i caratteri Unicode codificati in UTF-8 e i caratteri di escape CGI.

Esempio di utilizzo:

detox -r -v /path/to/your/files
-r Richiama nelle sottodirectory
-v Essere dettagliati su quali file vengono rinominati 
-n Può essere utilizzato per una corsa a secco (mostra solo cosa sarebbe cambiato)

2
Questo dovrebbe essere molto più alto, esorto tutti a dare un'occhiata detoxprima di reinventare essenzialmente la ruota. Se guardi la pagina man, vedrai che copre tutte le altre soluzioni proposte qui a causa della sua flessibilità.
emk2203,

Ezechiele 25:17 - Beato colui che, in nome della carità e della buona volontà, eleva questa soluzione, poiché è veramente il custode di suo fratello e il cercatore di bambini perduti.
Jan Sila,

Non intuitivamente, il percorso non può essere "." in debian. Se usi un '.' non trova nulla.
Isaaclw,

Mi chiedo se funziona davvero, sembra rimuovere / sostituire i caratteri cinesi, ad esempio 的节奏啊, ma quei caratteri sono nomi di file validi.
皞 皞

5

Questo script di shell disinfetta ricorsivamente una directory, per rendere i file portatili tra Linux / Windows e FAT / NTFS / exFAT. Rimuove i caratteri di controllo /:*?"<>\|e alcuni nomi di Windows riservati come COM0.

sanitize() {
  shopt -s extglob;

  filename=$(basename "$1")
  directory=$(dirname "$1")

  filename_clean=$(echo "$filename" | sed -e 's/[\\/:\*\?"<>\|\x01-\x1F\x7F]//g' -e 's/^\(nul\|prn\|con\|lpt[0-9]\|com[0-9]\|aux\)\(\.\|$\)//i' -e 's/^\.*$//' -e 's/^$/NONAME/')

  if (test "$filename" != "$filename_clean")
  then
    mv -v "$1" "$directory/$filename_clean"
  fi
}

export -f sanitize

sanitize_dir() {
  find "$1" -depth -exec bash -c 'sanitize "$0"' {} \;
}

sanitize_dir '/path/to/somewhere'

Linux è meno restrittivo in teoria ( /e \0sono severamente vietati nei nomi dei file) ma in pratica diversi personaggi interferiscono con i comandi bash (come *...), quindi dovrebbero essere evitati anche nei nomi dei file.

Grandi fonti per le restrizioni sulla denominazione dei file:


1
È quello che cerco! ma aggiungi le virgolette per supportare le directory con spazi trova "$ 1" -depth -exec bash -c 'sanitize "$ 0"' {} \;
mmv-ru,


0

Uso questo one-liner per rimuovere i caratteri non validi nei file dei sottotitoli:

for f in *.srt; do nf=$(echo "$f" |sed -e 's/[^A-Za-z0-9.-]/./g;s/\.\.\././g;s/\.\././g'); test "$f" != "$nf" && mv "$f" "$nf" && echo "$nf"; done
  1. Elabora solo i file * .srt (* può essere utilizzato al posto di * .srt per elaborare ogni file)
  2. Rimuove tutti gli altri caratteri tranne le lettere A-Za-z, i numeri 0-9, i punti "." E il trattino "-"
  3. Rimuove possibili periodi doppi o tripli
  4. Verifica se il nome del file deve essere modificato
  5. Se vero, rinomina il file con il comando mv, quindi genera le modifiche apportate con il comando echo

Funziona per normalizzare i nomi delle directory dei film:

for f in */; do nf=$(echo "$f" |sed -e 's/[^A-Za-z0-9.]/./g' -e 's/\.\.\././g' -e 's/\.\././g' -e 's/\.*$//'); test "$f" != "$nf" && mv "$f" "$nf" && echo "$nf"; done

Stessi passaggi precedenti ma ho aggiunto un altro comando sed per rimuovere un punto alla fine della directory

X-Men Days of Future Past (2014) [1080p]
Modificato in:
X-Men.Days.of.Future.Past.2014.1080p


-2

per file in *; do mv "$ file" $ (echo "$ file" | sed -e 's / [^ A-Za-z0-9. -] / / g'); fatto &


2
Dovresti spiegare cosa fa il tuo codice e usare la formattazione corretta. Il codice può causare l'eliminazione dei file introducendo collisioni nei nomi. E eseguire l'intera cosa in background è un po 'sciocco.
Kasperd,
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.