在我們的日常工作中,經常需要透過命令列工具來處理文字資料。而在Linux系統中,bash管道(pipe)是一個非常強大的工具,可以將一個指令的輸出作為另一個指令的輸入。但是,當我們透過管道接收到一大段文字流時,如何有效地讀取和格式化這些資料呢?本文將為大家介紹一些實用的技巧和方法,幫助你更好地處理透過bash管道接收的文字流。無論你是初學者還是有一定經驗的開發者,本文都將為你帶來一些啟發和幫助。
目前,我正在使用以下內容來格式化 npm 腳本中的資料。
npm run startwin | while ifs= read -r line; do printf '%b\n' "$line"; done | less
它可以工作,但我的同事不使用 linux。所以,我想實作 while ifs= read -r line;執行 printf '%b\n' "$line";在go中完成
,並在管道中使用二進位檔案。
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) } }
目前,程式會靜默文字流的所有輸出。
您想要使用 bufio.scanner 進行尾部類型讀取。恕我直言,您在 os.stdin
上進行的檢查是不必要的,但是 ymmv。
請參閱此答案以了解範例。 ioutil.readall()
(現已棄用,只需使用io.readall()
)讀取錯誤/eof,但它不是循環輸入- 這就是您需要bufio.scanner.scan()
的原因。 p>
此外 - %b
將轉換文字中的任何轉義序列 - 例如傳遞的行中的任何 \n
都會呈現為換行符號 - 您需要嗎? b/c go 沒有等效的格式說明符,afaik。
編輯
所以我認為,您基於 readall()
的方法將會/可能會起作用......最終。我猜您期望的行為與bufio.scanner
類似- 接收進程在寫入位元組時處理位元組(這實際上是一個輪詢操作- 請參閱scan()
的標準庫原始碼以查看骯髒的細節) .
但是 readall()
會緩衝讀取的所有內容,並且直到最終出現錯誤或 eof 才會回傳。我破解了readall()
的檢測版本(這是標準庫原始碼的精確副本,只有一點點額外的檢測輸出),您可以看到它在寫入位元組時正在讀取,但它只是沒有在寫入過程完成之前不會返回並產生內容,此時它會關閉管道的末端(其打開的文件句柄),從而生成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 } } }
我剛剛編寫了一個廉價的腳本來產生輸入,模擬一些長時間運行的東西並且僅定期編寫,我想像 npm 在你的情況下的表現如何:
#!/bin/sh for x in 1 2 3 4 5 6 7 8 9 10 do cat ./main.go sleep 10 done
順便說一句,我發現閱讀實際的標準庫程式碼確實很有幫助......或者至少在這樣的情況下很有趣。
以上是如何讀取和格式化透過 bash 管道接收的文字流?的詳細內容。更多資訊請關注PHP中文網其他相關文章!