430 Stimmen

Wie gibt man eine mehrzeilige Zeichenkette in Bash aus?

Wie kann ich in Bash eine mehrzeilige Zeichenfolge ausgeben, ohne mehrere echo-Aufrufe wie folgt zu verwenden:

echo "Verwendung: up [--level | -n ][--help][--version]"
echo 
echo "Fehler melden an: "
echo "up Homepage: "

Ich suche einen portablen Weg, dies zu tun, nur mit den in Bash integrierten Funktionen.

6 Stimmen

Wenn Sie eine Verwendungsnachricht als Antwort auf einen falschen Aufruf ausgeben, senden Sie diese normalerweise an den Standardfehlerausgang anstelle des Standardausgangs, mit echo >&2 ...

3 Stimmen

@MarkReed Die Verwendungsnachricht wird ausgegeben, indem --help eingegeben wird (was standardmäßig ausgegeben werden sollte).

3 Stimmen

Für andere, die vorbeikommen, gibt es weitere Informationen zu "here documents": tldp.org/LDP/abs/html/here-docs.html

24voto

Elliptical view Punkte 2740

Auch mit eingerücktem Quellcode können Sie <<- (mit einem abschließenden Bindestrich) verwenden, um führende Tabs zu ignorieren (aber keine führenden Leerzeichen).

Zum Beispiel dies:

if [ some test ]; then
    cat <<- xx
        line1
        line2
xx
fi

Gibt eingerückten Text ohne das führende Leerzeichen aus:

line1
line2

0 Stimmen

Das hat bei mir nicht funktioniert. Welche Shell benutzt du?

0 Stimmen

Funktionierte nicht in Bash 4.4.19 in Ubuntu. Es hat den Abstand vor Zeile1 und Zeile2 nicht entfernt

1 Stimmen

@four43, Du hattest recht. Es funktioniert nicht, führende Leerzeichen zu entfernen. Allerdings werden führende Tabs entfernt. Also habe ich meine Antwort von Tabs und Leerzeichen auf Tabs und nicht Leerzeichen korrigiert. Entschuldigung für den Fehler. Ich habe im Handbuch nachgeschaut und es steht klar drin, dass nur Tabs entfernt werden. Danke, dass du mich darauf hingewiesen hast.

21voto

Zstack Punkte 2718

Normalerweise verwende ich das integrierte read-Befehl, der meiner Meinung nach flexibler und intuitiver ist. Es liest den Inhalt einer Zeile in eine Variable ein und ermöglicht das Worttrennen, das mit der speziellen Shell-Variable IFS verknüpft ist. Weiterführende Informationen finden Sie in diesem Blog oder auch in der Man-Seite.

read -r -d '' usage <<-EOF
    Verwendung: up [--level | -n ][--help][--version] 

    Fehlermeldungen an: $report server
    up Startseite: $HOME
EOF
echo "$usage"

2 Stimmen

Das Beste daran ist, dass <<- (mit dem Minuszeichen) führende Tabulatorzeichen ignoriert, so dass Sie Ihre Nachricht im Code einrücken können, ohne sie beim Drucken einzurücken.

7voto

Ivan Punkte 4393

Noch eine Sache, Verwendung von printf mit vordefinierter Variable (hier: msg) als Vorlage.

msg="Erste Zeile %s
Zweite Zeile %s
Dritte Zeile %s
"

one='zusätzliche Nachricht für die erste Zeile'
two='2'
tri='das ist die letzte'

printf "$msg" "$one" "$two" "$tri"

Dieses ^^^ wird die gesamte Nachricht mit zusätzlichen Variablen anstelle von %s in der angegebenen Reihenfolge ausgeben.

0 Stimmen

Dies funktioniert gut in Makefiles

2voto

assayag.org Punkte 435
    Sie können Ihren
    Text
        frei schreiben,
                   in einer separaten: 
                             ----Datei.

und dann

echo "$(

1voto

Gabriel Staples Punkte 20228

Option 1: += Verkettungsoperator

Um die Formatierung auf einer Textzeile beizubehalten und mehrere Zeilen im Code zu verwenden, aber nicht beim Drucken, verwenden Sie den += Verkettungsoperator, wie folgt:

# Funktionsdefinition
some_func() {
    text="Dies ist der erste Teil eines wirklich langen Strings "
    text+="den ich in mehreren Zeilen schreiben möchte "
    text+="ohne mich um Einrückung sorgen zu müssen. Ich möchte auch, dass es in diesem Fall als eine Zeile gedruckt wird."

    echo "$text"
}

# Funktion aufrufen
some_func

Beispiel Ausgabe:

Dies ist der erste Teil eines wirklich langen Strings den ich in mehreren Zeilen schreiben möchte ohne mich um Einrückung sorgen zu müssen. Ich möchte auch, dass es in diesem Fall als eine Zeile gedruckt wird.

Hinweis/für Fortgeschrittene: Sie könnten erzwingen, Zeilenumbrüche im obigen Textstring zu setzen, wenn Sie wollten, indem Sie \n im Text verwenden, wie in echo -e "some text\n" oder printf "%s\n" "some text".

Option 2: dedent Funktion für natürlichen Text mit Zeilenumbrüchen

Sie können auch diesen Python-ähnlichen Trick anwenden:

dedent() {
    local -n reference="$1"
    reference="$(echo "$reference" | sed 's/^[[:space:]]*//')"
}

text="das ist Zeile eins
      das ist Zeile zwei
      das ist Zeile drei\n"

# `text` wird per Referenz übergeben und enteinzogen
dedent text

printf "$text"

Ausgabe OHNE Aufruf von dedent zuerst:

das ist Zeile eins
      das ist Zeile zwei
      das ist Zeile drei

...und MIT Aufruf von dedent zuerst (wie oben gezeigt):

das ist Zeile eins
das ist Zeile zwei
das ist Zeile drei

Für eine ausführlichere Erklärung siehe, wo ich bereits darüber geschrieben habe:

  1. Äquivalent zu Pythons textwrap dedent in bash
  2. Mehrzeiliger String mit zusätzlichem Platz (erhaltene Einrückung)

Und natürlich, danke an @Andreas Louv für das Zeigen des sed Teils dieser Funktion hier.

1 Stimmen

Hinweis: Keine Einrückung beibehalten. Siehe auch stackoverflow.com/a/63228433/724752

0 Stimmen

@DavidWiniecki, ja, das sollte ich irgendwann fixieren, indem ich eine kompliziertere und programmatische Version der dedent-Funktion schreibe. Dann kann ich sie zu einer Bash-Bibliothek machen, mit Unit-Tests und allem, und sie überall dort importieren (sourcen), wo sie benötigt wird, wie ich hier über Bash-Bibliotheken erkläre: Ausführliches Beispiel: Wie schreibt, importiert, verwendet und testet man Bibliotheken in Bash?. Das wäre cool.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X