Evitare di sostituire gli spazi durante la ridenominazione dei file


10

Sto cercando di rinominare i file in questo modo:

for file in *;
do
mv -i "$file" "$(echo "$file" | sed -e 's/[^A-Za-z0-9._-]/_/g')";
done

Ma il sedcomando sostituisce tutti gli spazi con _.

Come posso modificare il sedcomando per farlo includere spazi tra i caratteri specificati? Ho provato a usare \sma non funziona ...

EDIT:
Ad esempio: il file trip: hill, dovrebbe essere rinominato:, trip_ hillma il comando sopra lo rende trip__hill.


Sto trasferendo alcuni file da Linux a Mac. Ma per qualche motivo il sistema Mac non è in grado di leggere tutti i nomi dei file, quindi sto cercando di rinominare i miei file. L'aggiunta di uno spazio al comando sopra non funziona. E hai ragione: voglio sostituire tutti i caratteri con '_' tranne quelli specificati. E non so come includere il carattere spaziale.

Nota che sto cercando di sostituire tutti i caratteri con "_" tranne quelli specificati. Non esiste un modello particolare per i file che vengono rinominati, quindi non posso usare questo comando perl.

Risposte:


11

Non analizzare i nomi dei file con sed! L'output di echo "$file"potrebbe non essere affidabile.

Usa rename. Il 17.10 è necessario installarlo prima

sudo apt install rename

Poi:

rename -n -- 's/[^-A-Za-z0-9_ .]/_/g' *

Appunti

  • rimuovere -ndopo il test per rinominare effettivamente i file
  • -- end-of-options nel caso in cui un file inizi con -
  • [^-A-Za-z0-9_ .]caratteri che non vogliamo sostituire - inserisci il -primo o l'ultimo, quindi non può indicare un intervallo (viene trattato letteralmente in queste posizioni).
  • Gli spazi possono essere inclusi nella classe
  • . è trattato alla lettera (in altri contesti regex rappresenta qualsiasi personaggio e deve essere evitato).

Questo funziona anche in sed:

$ echo 'trip: hill' | sed 's/[^-A-Za-z0-9 _.]/_/g'
trip_ hill

Se aggiungo uno spazio alla fine nella tua versione, ricevo un errore:

$ echo 'trip: hill' | sed -e 's/[^A-Za-z0-9._- ]/_/g'
sed: -e expression #1, char 22: Invalid range end

Ma con -alla fine funziona:

$ echo 'trip: hill' | sed -e 's/[^A-Za-z0-9._ -]/_/g'
trip_ hill

Quindi forse la posizione del trattino ha causato il tuo problema quando hai aggiunto lo spazio. Ma il consiglio di non analizzare i nomi dei file è valido!


Questo comando funziona grazie. Hai anche identificato chiaramente gli errori nel comando che ho usato.

2
Grazie ancora. Si noti che non è necessario utilizzare la barra "\" in caso di utilizzo di sed. Perché questo aggiunge '\' all'elenco dei caratteri ignorati.

2
@latach Questa è una barra rovesciata, ma hai assolutamente ragione. Dopo aver provato e scavato, ho scoperto che .è letterale in una classe di personaggi. TIL!
Zanna,

2

Puoi anche semplicemente usare la shell, l'espansione dei parametri di Bash può fare la sostituzione:

for f in ./* ; do
    mv "$f" "${f//[^-A-Za-z0-9._ ]/_}"
done

La doppia barra indica di sostituire tutte le corrispondenze, a parte questo, la sintassi è semplice.

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.