An ein Rohr anhängen und weitergeben?

An ein Rohr anhängen und weitergeben?

Ich habe eine einfache Bash-Funktion, die zwei Zahlen dividiert:

echo "750/12.5" | bc

Ich möchte die Ausgabe von nehmen bcund /24das Ergebnis an eine andere Instanz von anhängen und weiterleiten bc.

Etwas wie:

echo "750/12.5" | bc | echo $1 + "/24" | bc

Wo $1ist das weitergeleitete Ergebnis?

echo "750/12.5/24" | bcPS: Mir ist klar, dass ich meine Frage eher auf das Anhängen von Text an ein Pipe-Ergebnis beziehen könnte .

Antwort1

Dies habe ich erreicht, indem ich seddas Zeilenende verwendet und ersetzt habe:

echo "my text" | sed 's/$/ more text/'

Kehrt zurück:

my text more text

Ihr Beispiel:

echo "750/12.5" | bc | sed 's/$/\/24/' | bc

Antwort2

Alternativer Ansatz:

TL;DR: Verwenden Sie es catzum Verketten mit stdin ( -) als Argument. Beachten Sie, dass Ihre verketteten Streams durch Zeilenumbrüche getrennt werden. Entfernen Sie es, wenn dies unerwünscht ist.

Leider ist dieser Ansatz für Ihren speziellen Anwendungsfall etwas umständlich, da bcer fehlschlägt, wenn sich in der Mitte des Ausdrucks ein Zeilenumbruch befindet:

$ echo "750/12.5" | bc | cat - <(echo "/24") | bc
60
(standard_in) 2: parse error

Sie können dies umgehen, indem Sie die neue Zeile aus dem ursprünglichen bcErgebnis löschen:

$ echo "750/12.5" | bc | tr -d '\n' | cat - <(echo "/24") | bc
2

Ich bin jedoch auf diese Frage gestoßen, als ich "bash append to pipe" gegoogelt habe, und in meinem Fall habe ich tatsächlichTunmöchten, dass zwischen den Verkettungen eine neue Zeile steht. Für diejenigen, die aus demselben Grund hier sind, verwenden Sie | cat - <(...):

$ echo foo | cat - <(echo bar)
foo
bar
$ echo foo | cat - <(echo bar) | sort | cat - <(echo last_line)
bar
foo
last_line
$ echo foo | cat - <(echo bar) | sort | cat <(echo header) - <(echo last_line)
header
bar
foo
last_line

Antwort3

Bei der einfachsten Option wird dies an den Pipe-Stream angehängt:

$ echo "750/12.5" | { bc; echo "/24"; }
60
/24

Dies führt jedoch zu einem unerwarteten Zeilenumbruch. Um dies zu vermeiden, müssen Sie entweder tr verwenden:

$ echo "750/12.5" | { bc | tr -d '\n' ; echo "/24"; }
60/24

Oder, angesichts der Tatsache, dass eine Befehlserweiterung nachfolgende Zeilenumbrüche entfernt:

$ printf '%s' $( echo "750/12.5" | bc ); echo "/24"
60/24

Die korrekte Vorgehensweise sollte jedoch wahrscheinlich folgendermaßen aussehen:

$ echo "$(echo "750/12.5" | bc )/24"
60/24

Zur Verwendung in bc könnte es wie folgt geschrieben werden:

$ bc <<<"$(bc <<<"750/12.5")/24"
2

Um eine angemessene Genauigkeit bei Gleitkommazahlen zu erreichen, sollte es etwa so aussehen:

$ bc <<<"scale=10;$(bc <<<"scale=5;750/12.5")/24"
2.5000000000

Beachten Sie, dass zwei Skalen erforderlich sind, da es zwei Instanzen von bc gibt.

Natürlich benötigt eine Instanz von bc nur eine Skala:

$ bc <<<"scale=5;750/12.5/24"

Tatsächlich sollten Sie es in Bezug auf eine Zeichenfolge betrachten:

$ a=$(echo "750/12.5")        # capture first string.
$ echo "$a/24" | bc           # extend the string
2

Der oben genannte Kommentar zum Maßstab ist hier weiterhin gültig.

Antwort4

Sie können Folgendes verwenden, awkum alles in die Pipe einzufügen/anzuhängen:

$ date | awk 'BEGIN{print "prefix line"} {print}  END{print "suffix  line"}'
prefix line
Mo 21. Aug 15:24:30 CEST 2023
suffix  line

Wo

  • date- ist Ihr Eingabekanal (hier beispielsweise das aktuelle Datum)
  • BEGIN{print "prefix line"}- dieser Block fügt die Ausgabe vor dem Hauptblock ein
  • {print}- druckt den Inhalt der Eingabepipe; hier könnte man bei Bedarf einige Verarbeitungen durchführen
  • END{print "suffix line"} - dies hängt die Ausgabe nach main an

Um dasselbe in einer einzelnen Zeile zu tun, verwenden Sie einfach printf:

$ date | awk 'BEGIN{printf("prefix line >> ")} {printf($0)}  END{printf(" << suffix  line")}'
prefix line >> Mo 21. Aug 15:32:08 CEST 2023 << suffix  line/upload/sc505enb/tmp>

$ echo "750/12.5" | bc | awk '{printf($0)}  END{printf("/24\n")}'
60/24

verwandte Informationen