Wie benenne ich Dateien mit Leerzeichen mithilfe der Linux-Shell um?

28

Ich habe eine Reihe von Dateien mit Leerzeichen benannt und möchte das Leerzeichen durch ersetzen _. Jedes Mal, wenn ich einen Befehl mit dem Dateinamen (z. B. Spring 2011) in die Shell schreibe , erkennt die Shell die Datei oder das Verzeichnis nicht.

Was kann ich dagegen tun? Gibt es eine Möglichkeit, das Unicode-Zeichen für ein Leerzeichen zu verwenden?

Phil Braun
quelle
Verwenden Sie zum programmgesteuerten Umbenennen von N-Dateien eine bashfor-Schleife ( siehe meine Lösung hier) .
Trevor Boyd Smith

Antworten:

33

Entfliehen Sie dem Raum zB Spring\ 2011oder verwenden Sie Anführungszeichen, zB 'Spring 2011'. In Zukunft ist es normalerweise eine schlechte Idee, Dateinamen mit Leerzeichen auf einem beliebigen * NIX zu verwenden.

Wenn Sie haben rename, können Sie dies verwenden:

rename ' ' '_' [filenames...]
Rafe Kettler
quelle
1
Weißt du, dass es sowieso möglich ist, dies für alle Dateien gleichzeitig zu tun?
3
Warum ist es eine schlechte Idee? Es liegt in der Verantwortung des Programmierers, mit Dateinamen richtig umzugehen.
Glenn Jackman
1
@rafe, es ist wirklich fehleranfällig, Dateinamen im Voraus nicht richtig zu behandeln. Der zusätzliche Aufwand entsteht beim Debuggen eines Skripts, wenn Sie einfach vergessen haben, Variablen mit einem Dateinamen in Anführungszeichen zu setzen.
Glenn Jackman
3
Diese Antwort scheint nicht zu funktionieren (zumindest unter Ubuntu 12.04 LTS). Die Antwort von unutbu funktioniert jedoch einwandfrei .
DNA
1
Dies hat nur das erste Leerzeichen für mich ... was nicht hilfreich ist (ich habe renameVersion 2.23)
Trevor Boyd Smith
30

Wenn Ihr Computer über den Befehl zum Umbenennen verfügt , werden alle Leerzeichen in allen Dateien / Verzeichnissen im aktuellen Arbeitsverzeichnis in Unterstriche umgewandelt:

rename 's/ /_/g' *
unutbu
quelle
Bestätigt, um in Ubuntu 12.04
anthonygore 10.10.14
1
hat bei mir nicht funktioniert ... ich habe die Fehlermeldung "Rename: nicht genügend Argumente" erhalten. Ich habe Version rename --version rename from util-linux 2.23.2.
Trevor Boyd Smith
24

Wenn Sie nicht renamenur die Shell haben oder bevorzugen:

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

Heruntergebrochen:

  • *\ *Wählt alle Dateien mit einem Leerzeichen im Namen als Eingabe für die forSchleife aus.
  • Die Anführungszeichen "$f"sind wichtig, da wir wissen, dass der Dateiname ein Leerzeichen enthält und es sonst als Argumente für 2+ erscheinen würde mv.
  • ${f//str/new_str}ist eine bash-spezifische Funktion zum Ersetzen von Zeichenfolgen. Alle Instanzen von strwerden durch ersetzt new_str.
blahdiblah
quelle
2
das funktioniert aber bei mir ersetzt es nur den ersten raum. wenn ich es benutze for f in *\ *; do mv "$f" "${f// /_}"; donefunktioniert
billynoah
@billynoah Guter Fang, aktualisiert.
Blahdiblah
@blahdiblah Vielen Dank! Du hast mir so viel Zeit gespart!
Guerilla
@blahdiblah deine Lösung ist viel eleganter als meine Lösung . Gut gemacht. Ich hätte nicht gedacht, dass der for-Loop-Glob funktionieren würde ... also habe ich den Glob außerhalb des for-Loops erstellt.
Trevor Boyd Smith
3

mv "Spring 2011.file" Spring_2011.file sollte die Befehlszeile anweisen, die Zeichenfolge in Anführungszeichen als einzelne Eingabe zu nehmen.

rockerest
quelle
Dies ist die einzige Antwort, die ich zur Arbeit bringen konnte.
Blakeoft
1

Um N-Dateien programmgesteuert umzubenennen, können Sie eine einfache bashfor-Schleife verwenden.

#!/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

Wenn Sie weniger als 5 Dateinamen haben, können Sie alle Dateinamen manuell eingeben und den renameBefehl wie in der obigen Lösung vorgeschlagen verwenden . Aber für mich ... ich bevorzuge die programmatische Lösung ... auch wenn es nur 4 Dateien gibt.

ps

Wenn Sie nicht mit Bashder Parametererweiterung von vertraut sind , können ${filename// /_}Sie den folgenden renameBefehl verwenden:

if ((0)); then
    mv -v "${filename}" "${filename// /_}"
else
    rename ' ' '_' "${filename}"
fi
Trevor Boyd Smith
quelle