Bash - Ersetzen Sie das Leerzeichen durch eine neue Zeile


70

Wie kann ich Leerzeichen in einer Eingabe durch neue Zeilen ersetzen?

/path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5 usw...

So erhalten Sie Folgendes:

/path/to/file
/path/to/file2
/path/to/file3
/path/to/file4
/path/to/file5

Hinweis

Ich poste diese Frage, um anderen Benutzern zu helfen. Unter UNIX SE war es nicht einfach, eine nützliche Antwort zu finden, bis ich mit der Eingabe dieser Frage begann. Danach habe ich folgendes gefunden:

Verwandte Frage

Wie kann ich eine neue Zeile finden und ersetzen?



ls / path / to / | xargs echo | sed 's / \ s \ + / \ n / g'
SD.

Antworten:



20

In diesem Fall würde ich printf verwenden:

printf '%s\n' /path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5

Wenn es Plätze sind innerhalb des einen des Weges, können Sie diesen Dateipfad , um zitieren zu verhindern , dass es auf den Räumen aufgeteilt werden:

printf '%s\n' /path/to/file '/path/to/file with spaces' /path/to/another/file

Das Transformieren von Text im Allgemeinen trist Ihre beste Wahl, wie in einer vorhandenen Antwort beschrieben.


1
Ein kurzer Hinweis aus der Zukunft: Vielen Dank für die Veröffentlichung dieser Lösung, sie war für mich im Vergleich zur Verwendung von "Echo" sehr zuverlässig.
Liesmith

5

Angenommen, Sie haben eine Zeichenfolge mit Leerzeichen als Trennzeichen:

newline_separated=${space_separated// /$'\n'}

Allerdings stellen Sie wahrscheinlich die falsche Frage. (Nicht unbedingt, zum Beispiel kann dies in einem Makefile vorkommen.) Eine durch Leerzeichen getrennte Liste von Dateinamen funktioniert nicht wirklich: Was passiert, wenn einer der Dateinamen Leerzeichen enthält?

Wenn ein Programm Dateinamen als Argumente erhält, dürfen Sie diese nicht mit Leerzeichen verbinden. Verwenden Sie "$@", um nacheinander darauf zuzugreifen. Obwohl echo "$@"die Argumente mit Leerzeichen dazwischen echogedruckt werden, ist dies auf Folgendes zurückzuführen : Die Argumente werden mit Leerzeichen als Trennzeichen gedruckt. somecommand "$@"Übergibt die Dateinamen als separate Argumente an den Befehl. Wenn Sie die Argumente in separaten Zeilen drucken möchten, können Sie verwenden

printf '%s\n' "$@"

Wenn Sie über durch Leerzeichen getrennte Dateinamen verfügen und diese in ein Array einfügen möchten, um sie zu bearbeiten, können Sie den Wert mithilfe einer nicht in Anführungszeichen gesetzten Variablenerweiterung nach Zeichen aufteilen IFS(Sie müssen die Platzhaltererweiterung mit deaktivieren set -f, andernfalls glob Muster werden im Wert erweitert):

space_separated_list='/path/to/file1 /path/to/file2 /path/to/file3'
IFS=' '; set -f
eval "array=(\$space_separated_list)"
for x in "${array[@]}"; do 

Sie können dies in eine Funktion einkapseln, die die -fEinstellung und den Wert von " Fertig" wiederherstellt IFS:

split_list () {
  local IFS=' ' flags='+f'
  if [[ $- = *f* ]]; then flags=; fi
  set -f
  eval "$1=($2)"
  set $flags
}
split_list array '/path/to/file1 /path/to/file2 /path/to/file3'
for x in "${array[@]}"; do 

Ändern Sie die richtige Antwort auf diese. Ich denke, es ist richtiger zu recherchieren, wie ich zu einer durch Leerzeichen getrennten Liste gekommen bin, und diese Informationen auf eine andere Weise abzurufen. Es wäre cool für Lernende wie mich, wenn Sie ein bisschen Ihr Snipnet kommentieren und uns sagen würden, was Dinge wie das lokale var IFS oder die Bedingung $ - = f tun. Diese Art von Dingen weiß eine Person, die einige Male bash verwendet, nicht.
Laconbass

@laconbass Ich habe eine kurze Erklärung hinzugefügt. Schauen Sie nach set -fund IFSlesen Sie das Bash-Handbuch, wenn Sie alle Details erfahren möchten. Siehe auch unix.stackexchange.com/questions/16192/…
Gilles,

@ Guilles Diese kurze Erklärung ist genug für mich und ich denke, es wird für viele andere sein. Ty für Ihre Zeit
Laconbass

Einstellung vor IFSOrt wird nicht wirksam
Eliran Malka

@ EliranMalka Ich habe keine Ahnung, was du damit meinst. Wenn sich ein Skript nicht wie gewünscht verhält, können Sie hier eine Frage stellen.
Gilles

4

Sei pragmatisch, benutze sed !!

sed 's/\s\+/\n/g' file

Oben steht, um ein oder mehrere Whitespace-Zeichen (\ s +) durch eine neue Zeile (\ n) zu ersetzen.

Das ist mehr oder weniger:

'substitute /one space or more/ for /newline/ globally'

1
Ersetzen Sie das Wechselgeld durch ein Ersatzgeld. Dafür steht das s!
Rob

@ Rob danke, denk daran, dass du die Antworten anderer bearbeiten kannst.
MGP

1
Wenn Sie mehrere Leerzeichen zwischen den Texten haben, erhalten Sie leere Zeilen. Sie müssen nach dem \ s ein '+' einfügen, um anzugeben, dass Sie mindestens ein Leerzeichen als genau ein Leerzeichen zugeordnet haben möchten. dh sed 's / \ s + / \ n / g'
DarkHeart

4

Alternativ zu tr@laconbass können Sie xargsin diesem Fall auch Folgendes verwenden :

echo "/path/to/file /path/to/file2 /path/to/file3 /path/to/file4  /path/to/file5"\
| xargs -n1

Der Vorteil ist, dass es auch mit mehreren Leerzeichen trfunktioniert , was nicht der Fall ist.


0

So habe ich es gemacht:

echo "/path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5" | sed 's/ /\
'/g

Beachten Sie die Verwendung der Eingabetaste nach dem Backslash im sedBefehl.


Was für Vor- und Nachteile hat seddas tr?
Laconbass

Ihr Komfortlevel :-) Ich denke, Sie können mehr damit anfangen, sedda es sich um einen Editor handelt, anstatt nur Zeichen zu übersetzen.
Unxnut

4
sedkann so viel mehr, ist dafür aber total übertrieben. trist das richtige Werkzeug für DIESEN Job, aber Kenntnisse sedund reguläre Ausdrücke werden sich sicherlich später als nützlich erweisen!
Rob

0

Ein anderer Ansatz, vorausgesetzt, die Zeile befindet sich in einer Variablen mit dem Namen line:

for path in $line;do echo $path;done

Dies macht sich die Tatsache echozunutze , dass Bash seine Argumente standardmäßig in Leerzeichen aufteilt und standardmäßig eine neue Zeile an seine Eingabe anfügt.


Ich habe dies auf meinem Ubuntu-System versucht, bevor ich diese Frage gestellt habe und es nicht zum Laufen bringen konnte.
Laconbass

0
echo word1 word2 ... | sed -e 'y/ /\n/;P;D'

ist eine weitere Methode, um durch Leerzeichen getrennte Wörter in durch Zeilenumbrüche getrennte Wörter umzuwandeln.


-1

Das folgende Skript ist leicht zu verstehen und leicht zu verwenden.

cat filename | tr ' ' '\n' | tee filename

2
Die Essenz Ihrer Antwort ( tr) ist dieselbe wie in der akzeptierten Antwort. Außerdem hat Ihre Antwort folgende Probleme: a) Der Befehl wird nicht mit 4 Leerzeichen eingerückt (-> Abschriftenlayout). B) Ihre Verwendung von catist nutzlos (Sie können es durch ersetzen < filename tr ' ' '\n'). c) Ihr Ausgabedateiname ist der gleiche wie der Eingabedateiname. Damit erstellen Sie ein Datenrennen.
Maxschlepzig

1
Abgesehen von der korrekten Analyse von maxschlepzig handelt es sich hierbei nicht um ein Skript, sondern um eine Reihe verbundener Befehle mit einem fest codierten Namen (da das Skript hoffentlich einen Header hat, der die zu verwendende Shell angibt und zwei Parameter für die Eingabe und Ausgabe verwendet). Abgesehen davon finden es 2 von 3 Personen in meinem Haushalt nicht leicht zu verstehen. Vielleicht ist das nicht repräsentativ, aber denken Sie daran, dass etwas, das Sie selbst verstehen (oder in diesem Fall zu verstehen glauben), immer einfach zu sein scheint.
Anthon
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.