Schwer zu lesen:
Dieser sieht viel zu bash-ähnlich aus :) (schwer zu lesen) für meinen allgemeinen Geschmack:
cat << EndOfMessage
This is line 1.
This is line 2.
Line 3.
EndOfMessage
Besser, einfacher zu lesen:
Lass uns etwas Pythonischeres machen (das ist immer noch bash):
text="this is line one
this is line two
this is line three\n"
dedent text
printf "$text" # auf dem Bildschirm anzeigen
printf "$text" > file.txt # in eine Datei drucken
Ah...das ist besser. :) Es erinnert mich an die Python textwrap.dedent()
Funktion die ich hier verwende.
So sieht die magische dedent
Funktion aus:
dedent() {
local -n reference="$1"
reference="$(echo "$reference" | sed 's/^[[:space:]]*//')"
}
Beispielausgabe auf dem Bildschirm:
this is line one
this is line two
this is line three
Ohne zuerst dedent text
aufzurufen, würde die Ausgabe so aussehen:
this is line one
this is line two
this is line three
Die Variable text
wird per Referenz an dedent
übergeben, sodass das, was innerhalb der Funktion geändert wird, die Variable außerhalb der Funktion beeinflusst.
Für weitere Details, Erklärungen und Referenzen siehe meine andere Antwort hier: Äquivalent zu Pythons textwrap dedent in bash
Problem mit deinem ursprünglichen Versuch
OP's Zitat (mit meiner Hervorhebung):
Ich bin sicher, dass es kein Leerzeichen nach jedem \n
gibt, aber wie kommt das zusätzliche Leerzeichen zustande?
Dein ursprünglicher Versuch sah so aus:
text="this is line one\n
this is line two\n
this is line three"
echo -e $text
...aber deine Ausgabe hatte ein zusätzliches Leerzeichen vor der 2. und 3. Zeile. Warum?
Durch Deduktion und Experimentieren komme ich zu dem Schluss, dass echo
das tatsächliche Zeilenumbruch am Ende der Zeile (das, was du bekommst, wenn du tatsächlich Enter drückst) in ein Leerzeichen umwandelt. Dieses Leerzeichen erscheint daher vor der Zeile direkt nach jedem \n
im Text.
Die Lösung ist also, den echten Zeilenumbruch am Ende jeder Zeile zu escapen, indem du einen Backslash \
am Ende jeder Zeile innerhalb der Anführungszeichen deines Strings setzt, so wie hier:
text="this is line one\n\
this is line two\n\
this is line three"
echo -e "$text"
Setze kein Leerzeichen vor diese abschließenden Backslashes (so wie hier: text="this is line one\n \
) oder das Leerzeichen wird direkt in deine Ausgabe zurückgehen und dasselbe Problem mit dem zusätzlichen Leerzeichen verursachen!
ODER benutze einfach meine Technik mit der dedent
Funktion oben, die auch die zusätzliche Funktionalität hat, mit deinem Code einzurücken damit er wirklich hübsch und lesbar aussieht.