Linux
我如何 grep 來自同一輸入的兩個值被管道傳輸到它?
CentOS 5.x
我正在嘗試建構一個 shell 腳本來搜尋通過標準輸入提供的數據。這是輸入流的範例:
Date: 1/1/11 Time: 12:00 AM Foo: 12345 Foo1: dskjflsdkjflksdjlfds Foo2: 123456789 Foo3: kdsjflskdjflkjsdlkfjsdlkjflksdjflkjsdklfjlksdjflk
此資訊不存在於文件中,它只會作為標準輸出從另一個應用程序實時發送到腳本。
我希望 sript 查看數據並解析出**Foo:和Foo2:**的值:將它們儲存為變數以供稍後在腳本中使用。
我修改後的腳本嘗試是這樣的:
#!/bin/bash while read data; do SearchCriteria1=$(echo "$data" | grep "Foo: " | cut -c 5-) SearchCriteria2=$(echo "$data" | grep "Foo2: " | cut -c 6-) echo $SearchCriteria1 >> test.1 echo $SearchCriteria2 >> test.2 done
完成的腳本實際上不會使用 test.1 或 test 2 文件。我只是將它們列在這裡,以便於範例。
在這個例子中,我希望 test.1 有:
12345
在這個例子中,我希望 test.2 有:
123456789
但是,當我對此進行測試時, test.1 和 test.2 都是空白的,並且我知道數據中包含有效資訊。
我錯過了一些明顯的東西。有人可以澄清一下嗎?
想想你的 grep 從哪裡得到他們的輸入。你沒有給他們輸入文件名,所以他們是從標準輸入中讀取的。他們的標準輸入是什麼?它沒有重定向,也沒有管道進入 grep,因此它們使用循環的繼承標準輸入執行。
read
只執行一次。它將第一行讀入$data
,您永遠不會在任何地方使用它(這應該是出現問題的線索)。然後第一個 grep 執行,它消耗所有輸入,第二個 grep 附加到同一輸入,因此它立即獲得 EOF。這可能更接近您想要的:
SearchCriteria1=$(echo "$data" | grep "Foo " | cut -c 10-) SearchCriteria2=$(echo "$data" | grep "Foo2 " | cut -c 13-)
最後的分號沒用,所以我把它們去掉了。
此外,您可能希望追加到
test.1
,test.2
否則循環中的每次迭代都會覆蓋前一個所寫的內容。縱觀全域,您似乎想要一個“多輸出 grep”。您的每行帶有單獨 grep 的讀取循環是實現它的一種方法,但效率不高。最近在https://stackoverflow.com/questions/11676350/grepping-a-20g-file-in-bash/11676853討論了其他一些方法