2016-07-30 3 views
2

Ich habe etwas Text, den ich mit einem Stachel von Rohren erstellt habe, und ich möchte das mit echo statt awk weiter manipulieren.Wie lautet der Parameteraufruf für STDIN, wenn Sie Objekte in ein Echo packen oder drucken?

sagen, dass ich:

a chain | of | commands | producing |stream | of text 

Ausbeuten:

line 1 text 
line 2 text 
line 3 text 

Aber wenn ich wollte Echo verwenden, so etwas zu tun:

a chain | of | commands | producing |stream | of text | echo ${STDIN%text} 

den gesamten Text abgeschnitten nach wo es Zeile sagt, wie würde ich verweisen, um dieses erwartete Ergebnis zu erhalten:

line 1 
line 2 
line 3 
+4

'echo' ist einfach nicht das richtige Werkzeug hier. Jede Lösung mit echo wird verworren und unnatürlich sein. sed oder awk sind am besten. –

Antwort

3

Ein Werkzeug wie awk ist am besten für Ihr Szenario:

a chain | of | commands | awk '{sub(/[[:blank:]]*text$/,"")}1' 

sub standardmäßig wirkt auf den gesamten Datensatz $0 und wird die Anzahl der Leerzeichen/Tabulatoren im Text abgerufen behalten.


Benötigen Sie mehr über awk? Überprüfen Sie [ this ].

+0

@JohnKugelman: Danke, aktualisiert – sjsam

+1

Auch alles, was die Ausgabe einer Pipeline in eine Bash-Array setzt, stürzt ab, wenn die Pipeline zu viel Ausgabe produziert. –

+0

@StephenC: Ich verstehe, dass, warum ich eine awk Lösung auch zur Verfügung stellen würde .. :) – sjsam

4

Während es wäre praktisch parameter expansions wie ${var%text}-stdin Eingang angewendet wird, wird die Schale nicht unterstützen - wie der Name schon sagt, Parametererweiterungen sind auf Parameter (Variablen).

Während Sie konnte Rohr Ihren Befehl an eine while IFS= read -r line ... Schleife und führen Sie die Expansion in der Schleife auf ${line} ein solcher Ansatz wäre langsam (und ausführlich).

Daher ist ein externes Dienstprogramm ist die beste Wahl hier, wie sed:

cat <<<$'line 1 text\nline 2 text\nline 3 text' | sed 's/text$//' 

Der obige sed Befehl ist genau das, was Ihre Parameter Expansion tun würde.
Wenn Sie auch den Platz vor 'Text' trimmen möchten: sed 's/ text$//'.
Um eine variable Anzahl von Feldern, einschließlich keines zu trimmen: sed 's/ *text$//'
eine variable Anzahl von Räumen zu schneiden, aber mindestens 1: sed 's/ \{1,\}text$//'

  • (Basic) regulären Ausdruck text$ entspricht jede Zeile, die in endet ($) text.

  • s/...// ersetzt dann den übereinstimmenden Teil durch nichts (die leere Zeichenfolge), wodurch das Suffix text entfernt wird.


sjsam's helpful answer zeigt eine awk -basierte Alternative.

+0

Die awk Antwort ist wohl am sinnvollsten. Danke – Tom

+0

@Tom: Die 'sed' Lösung wird gleich gut funktionieren (und ist etwas prägnanter), und die Leistung wird ähnlich sein, so dass in diesem speziellen Fall jede Lösung in Ordnung ist. Im Allgemeinen ist 'sed's strong suit auf Regex basierende Transformationen (wie in diesem Fall), wohingegen' awk' bei der feldbasierten Verarbeitung hervorragend ist. – mklement0

Verwandte Themen