我一直在嘗試使用 awk 重寫 egrep 命令以提高性能,但沒有成功。egrep 命令針對 file2 中的(部分匹配)記錄執行簡單的不區分大小寫的搜索。下面是命令和示例輸出。
檔案 1 包含:
Abc
xyz
123
blah
hh
a,b
檔案 2 包含:
abc de
xyz
123
456
blah
test1
abdc
abc,def,123
kite
a,b,c
原始命令:
egrep -i -f file1 file2
原始(egrep)命令輸出:
$ egrep -i -f file1 file2
abc de
xyz
123
blah
abc,def,123
a,b,c
我想用AWK重寫命令來做同樣的操作。我已經嘗試過以下方法,但它正在執行完整的記錄匹配,而不是像 grep 那樣部分匹配。
awk 中的修改命令:
awk 'NR==FNR{a[tolower($0)];next} tolower($0) in a' file1 file2
修改后的命令(awk)輸出:
$ awk 'NR==FNR{a[tolower($0)];next} tolower($0) in a' file1 file2
xyz
123
blah
這不包括與字串“abc”部分匹配的記錄。請幫助修復 awk 命令?提前致謝。
uj5u.com熱心網友回復:
像這樣使用index部分文字匹配:
awk '
NR == FNR {
needles[tolower($0)]
next
}
{
haystack = tolower($0)
for (needle in needles) {
if (index(haystack, needle)) {
print
break
}
}
}' file1 file2
uj5u.com熱心網友回復:
我會有點驚訝它比它快得多,egrep但你可以試試這個:
$ awk 'NR==FNR {r=r ((r=="")?"":"|") tolower($0);next} tolower($0)~r' file1 file2
abc de
xyz
123
blah
abc,def,123
說明:首先從 的內容構建r1|r2|...|rn正則運算式file1并將其存盤在awk變數中r。然后列印匹配它的所有行file2,這要歸功于~match 運算子。
如果你有 GNU awk,你可以使用它的IGNORECASE變數而不是tolower:
$ awk -v IGNORECASE=1 'NR==FNR{r=r ((r=="")?"":"|") $0;next} $0~r' file1 file2
abc de
xyz
123
blah
abc,def,123
而對于 GNU awk,可能是強制型別rtoregexp而不是string導致更好的性能。手冊說:
鑒于您可以使用正則運算式和字串常量來描述正則運算式,您應該使用哪個?答案是“正則運算式常量”,原因如下:
...
使用正則運算式常量更有效。'awk' 可以注意到您提供了一個正則運算式并將其存盤在內部以使模式匹配更有效的形式。當使用字串常量時,'awk' 必須首先將字串轉換成這種內部形式,然后執行模式匹配。
為此,您可以嘗試:
$ awk -v IGNORECASE=1 'NR==FNR {s=s ((s=="")?"":"|") $0;next}
FNR==1 && NR!=FNR {r=@//;sub(//,s,r);print typeof(r),r} $0~r' file1 file2
regexp Abc|xyz|123|blah|hh
abc de
xyz
123
blah
abc,def,123
(r=@//強制變數r是型別regexp并且sub(//,s,r)不會改變它)
注意:就像您的egrep嘗試一樣,行file1被視為正則運算式,而不是要搜索的簡單文本字串。file1因此,如果is中的一行,則其中的.*所有行都file2將匹配,而不僅僅是包含 substring 的行.*。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/517592.html
標籤:重击awk
上一篇:重命名變體列
