Bei unserer täglichen Arbeit müssen wir Textdaten häufig über Befehlszeilentools verarbeiten. In Linux-Systemen ist Bash Pipe (Pipe) ein sehr leistungsfähiges Tool, das die Ausgabe eines Befehls als Eingabe eines anderen Befehls verwenden kann. Aber wie können wir diese Daten effizient lesen und formatieren, wenn wir einen großen Textstrom über eine Pipe empfangen? In diesem Artikel werden Ihnen einige praktische Tipps und Methoden vorgestellt, die Ihnen helfen, über Bash-Pipes empfangene Textströme besser zu verarbeiten. Egal, ob Sie Anfänger oder erfahrener Entwickler sind, dieser Artikel wird Ihnen Inspiration und Hilfe bieten.
Derzeit verwende ich Folgendes, um Daten in einem NPM-Skript zu formatieren.
npm run startwin | while ifs= read -r line; do printf '%b\n' "$line"; done | less
Es funktioniert, aber mein Kollege verwendet kein Linux. Also möchte ich while ifs= read -r line;执行 printf '%bn' "$line";在go中完成
implementieren und die Binärdatei in der Pipeline verwenden.
npm run startwin | magical-go-formater
package main import ( "fmt" "io/ioutil" "os" "strings" ) func main() { fi, _ := os.Stdin.Stat() // get the FileInfo struct if (fi.Mode() & os.ModeCharDevice) == 0 { bytes, _ := ioutil.ReadAll(os.Stdin) str := string(bytes) arr := strings.Fields(str) for _, v := range arr { fmt.Println(v) } }
Derzeit schaltet das Programm alle Ausgaben des Textstreams stumm.
Sie möchten bufio.scanner zum Lesen von Schwanztypen verwenden. Meiner Meinung nach ist die Überprüfung, die Sie am os.stdin
durchgeführt haben, unnötig, aber ymmv.
Siehe diese Antwort für ein Beispiel. ioutil.readall()
(现已弃用,只需使用 io.readall()
)读取错误/eof,但它不是循环输入 - 这就是您需要 bufio.scanner.scan()
Gründe. p>
Außerdem – %b
将转换文本中的任何转义序列 - 例如传递的行中的任何 n
werden alle als Zeilenumbrüche gerendert – brauchen Sie das? b/c go hat keinen entsprechenden Formatbezeichner, afaik.
Bearbeiten
Ich denke also, Sie haben den Quellcode der Standardbibliothek von readall()
的方法将会/可能会起作用......最终。我猜您期望的行为与 bufio.scanner
类似 - 接收进程在写入字节时处理字节(这实际上是一个轮询操作 - 请参阅 scan()
zugrunde gelegt, um die schmutzigen Details zu sehen) .
Aber bei der instrumentierten Version von readall()
会缓冲读取的所有内容,并且直到最终出现错误或 eof 才会返回。我破解了 readall()
(die eine exakte Kopie des Quellcodes der Standardbibliothek ist, mit nur einer kleinen zusätzlichen Instrumentierungsausgabe) können Sie sehen, dass sie liest, während die Bytes geschrieben werden, aber sie wird einfach nicht fertig vor dem Schreibvorgang Es kehrt nicht zurück und produziert vorher keinen Inhalt. An diesem Punkt schließt es das Ende der Pipe (sein offenes Dateihandle) und erzeugt so ein eof:
package main import ( "fmt" "io" "os" "time" ) func main() { // os.stdin.setreaddeadline(time.now().add(2 * time.second)) b, err := readall(os.stdin) if err != nil { fmt.println("error: ", err.error()) } str := string(b) fmt.println(str) } func readall(r io.reader) ([]byte, error) { b := make([]byte, 0, 512) i := 0 for { if len(b) == cap(b) { // add more capacity (let append pick how much). b = append(b, 0)[:len(b)] } n, err := r.read(b[len(b):cap(b)]) //fmt.fprintf(os.stderr, "read %d - received: \n%s\n", i, string(b[len(b):cap(b)])) fmt.fprintf(os.stderr, "%s read %d - received %d bytes\n", time.now(), i, n) i++ b = b[:len(b)+n] if err != nil { if err == io.eof { fmt.fprintln(os.stderr, "received eof") err = nil } return b, err } } }
Ich habe gerade ein billiges Skript geschrieben, um Eingaben zu generieren, einige lang laufende Dinge zu simulieren und nur in regelmäßigen Abständen zu schreiben. Ich stelle mir vor, wie sich npm in Ihrem Fall verhalten würde:
#!/bin/sh for x in 1 2 3 4 5 6 7 8 9 10 do cat ./main.go sleep 10 done
Übrigens finde ich das Lesen des tatsächlichen Standardbibliothekscodes wirklich hilfreich ... oder zumindest in solchen Fällen interessant.
Das obige ist der detaillierte Inhalt vonWie lese und formatiere ich einen über eine Bash-Pipe empfangenen Textstream?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!