Grep

帶有退出條件的 Grep

  • February 6, 2022

我有一個巨大的文件,我想用 grep 的簡單過濾器顯示它:

假設這是我的文件:

TIME0 random data
TIME1 random data
TIME2 INTERESTING LINE
TIME3 random data
TIME4 random data
TIME5 random data
TIME6 random data
TIME7 INTERESTING LINE
TIME8 random data
TIME9 random data
TIME10 random data
TIME11 INTERESTING LINE
TIME12 random data

我想顯示INTERESTING LINE

grep "INTERESTING LINE" myfile

這可行,但文件很大,包含數百萬個INTERESTING LINE。我只需要最後一個:

tac myfile | grep -m3 "INTERESTING LINE"

這行得通,但是我怎樣才能指定我只在某個TIME前綴之後才需要INTERESTING LINE ?(或直到某個時間tac

因此,例如使用上面的範例文件,我如何才能從 myfile 中 grep 所有INTERESTING LINE**從最後到TIME7?(所以不需要 TIME2 的有趣行):

TIME11 INTERESTING LINE
TIME7 INTERESTING LINE

訂購併不重要,我可以接受 ASC 或 DESC 訂購。

重要的是不要掃描整個文件,即從文件末尾逐行掃描。

我正在尋找一種為 grep 提供退出標準的方法(而不是用 定義最大結果數-m

使用sed而不是grep更好地控制輸入數據的解析:

$ tac file | sed -n -e '/^TIME6 /q' -e '/INTERESTING LINE/p'
TIME11 INTERESTING LINE
TIME7 INTERESTING LINE

這將tac按照您的建議反轉文件,並將反轉的數據通過sed.

兩種sed表達方式:

  • /^TIME6 /q, 一旦我們找到以 . 開頭的行就退出TIME6 。您還可以使用/^TIME[0-6] /q或任何與時間列匹配的表達式,這些時間列太舊而無法引起人們的興趣。
  • /INTERESTING LINE/p, 列印與給定正則表達式匹配的所有行。

效果是文件只被讀取,直到我們發現時間戳太新。在解析過程中發現的任何有趣的行都會列印到標準輸出。

如果您知道TIME7要搜尋的確切時間戳,直到:

$ tac file | sed -n -e '/INTERESTING LINE/p' -e '/^TIME7 /q'
TIME11 INTERESTING LINE
TIME7 INTERESTING LINE

如果感興趣的話,這允許我們列印最後讀取的行,即使它正是我們想要退出的時間戳。

引用自:https://unix.stackexchange.com/questions/689512