Come posso rinominare i file con spazi usando la shell Linux?


28

Ho chiamato un numero di file con spazi in essi e voglio sostituire lo spazio con _. Tuttavia, ogni volta che scrivo un comando nella shell con il nome del file (ad es. Spring 2011), La shell non riconosce il file o la directory.

Cosa posso fare al riguardo? Esiste un modo per utilizzare il carattere unicode per uno spazio?


per rinominare a livello di codice N file, utilizzare un bashciclo for: vedere la mia soluzione qui .
Trevor Boyd Smith,

Risposte:


33

Sfuggire allo spazio, ad esempio Spring\ 2011, o utilizzare le virgolette, ad esempio 'Spring 2011'. In futuro, in genere è una cattiva idea utilizzare nomi di file con spazi in essi su qualsiasi * NIX.

Se hai rename, puoi usare questo:

rename ' ' '_' [filenames...]

1
Sai c'è comunque di fare questo per tutti i file contemporaneamente?

3
Perché è una cattiva idea? È responsabilità del programmatore gestire correttamente i nomi dei file.
Glenn Jackman,

1
@rafe, in realtà è soggetto a errori non gestire correttamente i nomi dei file. Lo sforzo extra arriva quando devi eseguire il debug di uno script quando hai semplicemente dimenticato di citare le variabili che contengono un nome file.
Glenn Jackman,

3
Questa risposta non sembra funzionare (almeno su Ubuntu 12.04 LTS). La risposta di unutbu funziona bene però.
DNA,

1
questo ha fatto solo il primo spazio per me ... il che non è utile (ho la renameversione 2.23)
Trevor Boyd Smith

30

Se la tua macchina ha il comando rename , questo cambierà tutti gli spazi in caratteri di sottolineatura in tutti i file / directory nella directory di lavoro corrente:

rename 's/ /_/g' *

Confermato di funzionare in Ubuntu 12.04
anthonygore,

1
non ha funzionato per me ... ho ricevuto un errore di "rinomina: argomenti insufficienti". ho una versione rename --version rename from util-linux 2.23.2.
Trevor Boyd Smith,

-bash: /usr/bin/rename: Argument list too long
nmz787

24

Se non hai renameo preferisci usare solo la shell:

for f in *\ *; do mv "$f" "${f// /_}"; done

Suddiviso:

  • *\ *seleziona tutti i file con uno spazio nel loro nome come input per il forciclo.
  • Le virgolette in giro "$f"sono importanti perché sappiamo che c'è uno spazio nel nome del file e altrimenti sembrerebbe come 2+ argomenti mv.
  • ${f//str/new_str}è una funzione di sostituzione stringa specifica per bash. Tutte le istanze di strvengono sostituite con new_str.

2
questo funziona ma per me sostituisce solo il primo spazio. se lo uso for f in *\ *; do mv "$f" "${f// /_}"; donefunziona
billynoah

@billynoah Buona cattura, aggiornata.
blahdiblah,

@blahdiblah Grazie mille! Mi hai appena risparmiato così tanto tempo!
Guerrilla,

@blahdiblah la tua soluzione è molto più elegante della mia soluzione . buon lavoro. Non pensavo che il glob for loop avrebbe funzionato ... quindi ho fatto il glob al di fuori del for loop.
Trevor Boyd Smith,

3

mv "Spring 2011.file" Spring_2011.file dovrebbe dire alla riga di comando di prendere la stringa tra virgolette come un singolo input.


Questa è l'unica risposta che potrei mettermi al lavoro.
Blakeoft,

1

Per rinominare a livello di codice N file, è possibile utilizzare un semplice bashciclo per.

#!/bin/bash

set -eux

# find all your files by using a `grep` pattern
pattern="insert_filename_pattern_here" # you must enter your filename pattern here

# create an array of filenames and split on newlines
IFS=$'\n'
tmp=($(ls | grep ${pattern}))
unset IFS

# for each filename
for filename in "${tmp[@]}"; do
    # rename the filename to use "_" character instead of a " " character
    mv -v "${filename}" "${filename// /_}"
done

Se hai meno di 5 nomi di file, puoi digitare manualmente tutti i nomi di file e utilizzare il renamecomando come suggerisce la soluzione sopra . Ma per me ... preferisco la soluzione programmatica ... anche quando ci sono solo 4 file.

ps

se non si ha familiarità con Bashl'espansione dei parametri (ovvero ${filename// /_}) è possibile utilizzare il renamecomando:

if ((0)); then
    mv -v "${filename}" "${filename// /_}"
else
    rename ' ' '_' "${filename}"
fi
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.