Linux

我如何 grep 來自同一輸入的兩個值被管道傳輸到它?

  • August 13, 2012

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.1test.2否則循環中的每次迭代都會覆蓋前一個所寫的內容。

縱觀全域,您似乎想要一個“多輸出 grep”。您的每行帶有單獨 grep 的讀取循環是實現它的一種方法,但效率不高。最近在https://stackoverflow.com/questions/11676350/grepping-a-20g-file-in-bash/11676853討論了其他一些方法

引用自:https://serverfault.com/questions/416830