Ich stelle eine Präsentation für ein nicht-technisches Publikum zusammen. Ich habe ein Programm, das in Bash ausgeführt wird und einen kontinuierlichen Strom von Werten ausgibt, von denen einige wichtig sind. Ich möchte die wichtigen Ergebnisse hervorheben, die angezeigt werden, damit sich das Publikum einen Eindruck von ihrer Häufigkeit verschaffen kann. Das Problem ist, dass ich nicht sed
in der Lage bin, mit einem laufenden Stream zu arbeiten. Es funktioniert gut, wenn ich die Ergebnisse in eine Datei lege, wie in:
cat output.txt | sed "s/some text/some text bolded/"
Aber wenn ich das Gleiche auf der laufenden Ausgabe versuche, wie folgt:
command | sed "s/some text/some text bolded/"
sed
tut nichts. Irgendwelche Gedanken?
Wie Lambert hilfreich genug war, um darauf hinzuweisen, war mein Sprichwort, sed
das nichts bewirkt, vage. Was passiert ist, dass das Programm wie gewohnt auf ausgibt stdout
(ich bin mir ziemlich sicher, dass es nicht schreibt stderr
), auch wenn es durchgeleitet wird sed
.
Das Problem scheint zu sein, dass der Befehl ein zweites Programm aufruft, das dann auf stdout ausgegeben wird. Das erste Programm druckt einige Zeilen. diese kann ich bearbeiten. Dann gibt es einen Strom von Werten, die vom zweiten Programm gedruckt werden. diese kann ich nicht bearbeiten.
Perl- und awk-Methoden funktionieren auch nicht.
quelle
stdbuf -o0 command | sed "s/some text/some text bolded/"
Arbeit?command|egrep 'some text|$'
g
"globale" Ersetzung hinzufügen , da sonst nur das erste Vorkommen in einer Zeile ersetzt wird:sed "s/old/new/g"
Antworten:
Möglicherweise wird die Ausgabe des Befehls zwischengespeichert. Wenn der Befehl in ein Terminal schreibt, wird der Puffer in jeder neuen Zeile geleert, sodass er mit der erwarteten Rate angezeigt wird. Wenn der Befehl in eine Pipe schreibt, wird der Puffer nur dann geleert, wenn er einige Kilobyte erreicht, sodass er viel verzögert. Dies ist das Standardverhalten der Standard-Ein- / Ausgabebibliothek.
Um den Befehl zu zwingen, seine Ausgabe nicht zu bündeln, können Sie
unbuffer
(from expect) oderstdbuf
(from GNU coreutils) verwenden.quelle
stdbuf
hat nicht funktioniert (es wurde bereits erwähnt, übrigens), aberunbuffer
hat !! Du hast keine Ahnung, wie glücklich du mich gemacht hast.sed
selbst verwendet ein solcher Puffer, (cf ChennyStar post) , so dass die hier Beispiele kann nicht funktionieren , dased
das istcommand
zu unbuffer:cat /etc/passwd | unbuffer sed
abersed
selbst eine hat-u
Option, sogrep
suiteable in diesen Beispielen mehr sein könnte. Vielen Dank für Ihre Hintergrundinformationen! Gute Antwort!sed
hat eine Option dafür:Dadurch werden minimale Datenmengen aus den Eingabedateien geladen und die Ausgabepuffer häufiger geleert. Sehen Sie
man sed
für weitere Details.quelle
sed
Nur GNU (nicht BSDsed
), und ich glaube, dies würde das Puffern des Befehls am Pipe-Start immer noch nicht verhindern. Aber gut zu erwähnen. :)Ich würde awk benutzen
wo
/some important stuff/
wähle eine wichtige Zeile aus, wie in sedprintf "%c[31m%s%c[0m\n",27,$0,27 ;
rot druckenDer entscheidende Punkt ist, dass
command
die Linien bündig sein sollten, aber das sollte der Fall sein, wenn Sie viel Output haben.quelle
awk
(usingsub()
orgsub()
) zu implementieren , ist im Falle dieser primitiven Substitutionsed
sicherlich das geeignete Werkzeug.Die perl weg:
oder mit einer kontinuierlichen Ausgabe:
Ein Bash-Skript für die Ausgabe
cont
:Testen Sie mit:
\x1b[1m
- Fett oder erhöhte Intensität${1}
- das backreferenze\x1b[0m
- Alle Attribute zurücksetzenAusgabe:
Weitere Escape-Codes hier .
quelle