如何使用 grep 獲取組結果?
我將如何獲得此輸出:
Found value: This order was placed for QT3000! OK?
或者
Found value: This order was placed for QT300
或者
Found value: 0
使用
line.txt
和pattern.txt
如下:[nsaunders@rolly regex]$ [nsaunders@rolly regex]$ grep -e -f pattern.txt line.txt [nsaunders@rolly regex]$ [nsaunders@rolly regex]$ cat pattern.txt (.*)(\\d+)(.*) [nsaunders@rolly regex]$ [nsaunders@rolly regex]$ cat line.txt This order was placed for QT3000! OK? [nsaunders@rolly regex]$
利用類似於正則表達式教程
m.group(0)
的內容。也許
grep
沒有這樣的概念:Groups and capturing Group number Capturing groups are numbered by counting their opening parentheses from left to right. In the expression ((A)(B(C))), for example, there are four such groups: 1 ((A)(B(C))) 2 (A) 3 (B(C)) 4 (C) Group zero always stands for the entire expression. Capturing groups are so named because, during a match, each subsequence of the input sequence that matches such a group is saved. The captured subsequence may be used later in the expression, via a back reference, and may also be retrieved from the matcher once the match operation is complete.
假設中的模式
pattern.txt
是(.*)(\d+)(.*)
那麼,將它與 GNU 一起使用
grep
將是一個問題grep -E -f pattern.txt line.txt
即,搜尋與 中
line.txt
列出的任何擴展正則表達式匹配的行pattern.txt
,給定問題中的數據,生成This order was placed for QT3000! OK?
您的命令的問題是您使用了
-e -f
. 該-e
選項用於明確表示“下一個參數是表達式”。這意味著-e -f
將被解釋為“要使用的正則表達式是-f
”。然後,您將其應用於在命令行中提到的兩個文件中搜尋匹配項。次要問題是文件
\\d
中的pattern.txt
,它與後跟字元的反斜杠匹配d
,即文字字元串\d
。該模式還有一些其他“問題”。它首先使用非標準表達式來匹配數字,
\d
. 最好將其寫為[[:digit:]]
範圍或範圍[0-9]
(在 POSIX 標準語言環境中)。由於正則表達式匹配子字元串,而不是始終自動錨定的文件名通配模式,因此.*
不需要模式的任何位。同樣,括號根本不需要,因為它們在模式中沒有任何作用。也不需要,+
因為單個數字將與前面的表達式匹配(單個數字是“一個或多個數字”)。這意味著要提取包含(至少)一個數字的所有行,您可以改用模式
[[:digit:]]
or[0-9]
,或者\d
如果您想繼續使用 GNU 的類似 Perl 的表達式grep
,而無需其他修飾。有關這些之間的區別,請參閱之間的區別$$ 0-9 $$,$$ [:digit: $$] 和 \d。要獲得您在問題中顯示的三種不同輸出,請使用
sed
而不是grep
. 你想使用sed
因為grep
只能列印匹配的行(或單詞),而不能真正修改匹配的數據。
Found value:
在任何包含數字的行前面插入,並列印這些行:$ sed -n '/[[:digit:]]/s/^/Found value: /p' line.txt Found value: This order was placed for QT3000! OK?
Found value:
在包含數字的任何行前面插入,並將這些行列印到找到的第 3 個數字的末尾(或最多到第 3 個數字;如果第一個子字元串中的連續數字較少,則可能在末尾輸出較少的數字線上的數字):$ sed -n '/[[:digit:]]/s/\([^[:digit:]]*[[:digit:]]\{1,3\}\).*/Found value: \1/p' line.txt Found value: This order was placed for QT300
Found value:
在任何包含數字的行前面插入,並列印該行的最後一個數字:$ sed -n '/[[:digit:]]/s/.*\([[:digit:]]\).*/Found value: \1/p' line.txt Found value: 0
使用您使用的等效正則表達式,我們可以看到它匹配的文本位:
$ sed 's/\(.*\)\([[:digit:]]\{1,\}\)\(.*\)/(\1)(\2)(\3)/' line.txt (This order was placed for QT300)(0)(! OK?)
請注意,
\2
僅匹配行上的最後一位數字,因為前面.*
是貪婪的。