Grep

需要在模式旁邊或下方搜尋單詞

  • November 25, 2022

我在 i 中有一個包含以下行的文件:

   .......... FROM ABCD_EXT
   .......... FROM HEG_EXT1 
.......... from
          xyz_EXT
.......... FROM abd_EXT2 
..........where QWT_EXT.SID=POI_EXT.GET
..........where QWT_EXT.SID=POI_GET.END_EXT

我只需要 grep 僅在“FROM”(不區分大小寫)旁邊或下方且以 _EXT 結尾的單詞。

即,預期輸出是:

ABCD_EXT 
xyz_EXT

編輯:是的,無論它出現在同一行還是下一行,我都需要在“from”之後搜尋下一個詞。

我試過這個,它讓我正確地獲得了第一部分(同一行):

grep _EXT rt.sql |grep -i from|sed -e 's/_EXT/_EXT /g'|awk '{print $NF}'|grep _EXT

從下面一行中獲取單詞是問題所在。

pcregrep

pcregrep -Mo1 '(?<!\S)(?i:from)\s+(\S*_EXT)(?!\S)' < rt.sql
  • -M對於M多行模式
  • -o1輸出與st擷取組o匹配的內容。1
  • \s匹配一個空白字元(至少包括空格、製表符、CR 和 LF),\S匹配一個非空白字元。
  • x+: 匹配1個或多個xs
  • x*: 匹配0個或多個x
  • (?i:from): from, 不區分大小寫 與[fF][rR][oO][mM].
  • (?<!\S): 非空白的負面回顧,或者 IOW提供之前的內容不是非空白(空白或主題的開頭也是如此)。
  • (?!\S): 相同但向前看而不是向後看。如果它是 SQL,您可能也希望;允許(?![^\s;])

如果您沒有pcregrep,您可以perl改用(第一個pin pcregrep),並用 slurp 整個文件-0777

perl -l -0777 -ne 'print for /(?<!\S)(?i:from)\s+(\S*EXT)(?!\S)/g' < rt.sql

grep或者如果使用 PCRE 支持建構的 GNU (它添加了-P使用類似 perl 的正則表達式進行匹配的選項):

grep -zPo '(?<!\S)(?i:from)\s+\K\S*EXT(?!\S)' < rt.sql | tr '\0' '\n'

由於 GNUgrep不支持-o<n>輸出n第 th 個擷取組匹配的內容,我們改為使用-o輸出匹配的全部內容,但使用\K告訴匹配器將什麼K作為匹配。

由於-z我們處理以 NUL 分隔的記錄而不是行,因此假設輸入不包含 NUL(通常 SQL 和文本應該是這種情況),那將只是一個記錄構成文件的全部內容,就像在 perl 中一樣上面的 slurp 模式。不過,輸出記錄分隔符也將為 NUL,因此我們需要將tr它們轉換為換行符,以便在不同的行上進行每個匹配。

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