我有一个离散元素列表,我想测试文件每行中是否包含一个条目。我想用一种简洁的方法在awk中创建一个列表或数组,然后根据该列表测试每一行。
我的离散元素列表:
端口=(101020230308888、12345(
myFile:
127.0.0.1 1010
127.0.0.1 1011
127.0.0.1 12345
127.0.0.1 3333
我的伪代码:
awk '
BEGIN {
test_ports=[1010, 2020, 3030, 8888, 12345]
}
($2 in test_ports) {
print $0
}
' myFile
下面的代码可以工作,但它并不简洁,我不喜欢它随着列表的增长而增长,比如如果我有100个端口要测试,或者1000…
awk '
BEGIN {
test_ports["1010"]=1
test_ports["2020"]=1
test_ports["3030"]=1
test_ports["8888"]=1
test_ports["12345"]=1
}
($2 in test_ports) {
print $0
}
' myFile
这样的东西也不错,但语法不太正确:
for i in 1010 2020 3030 8888 12345 {test_ports[i]=1}
编辑
这段代码也很有效,非常接近我所需要的,但对于它正在做的事情来说,它似乎还有点长。
awk '
BEGIN {
ports="1010,2020,3030,8888,12345"
split(ports, ports_array, ",")
for (i in ports_array) {test_ports[ports_array[i]] = 1}
}
($2 in test_ports) {
print $0
}
' myFile
您可以这样使用它:
awk '
BEGIN {
ports = "1010 2020 3030 8888 12345" # ports string
split(ports, temp) # split by space in array temp
for (i in temp) # populate array test_ports
test_ports[temp[i]]
}
$2 in test_ports # print rows with matching ports
' myFile
127.0.0.1 1010
127.0.0.1 12345
解释说明:
temp
是一个数字索引数组,其中端口(10102020等(是从1开始索引的数组值test_ports
是一个关联数组,其中端口为数组键,值为null- CCD_ 4运算符测试给定元素是否是数组的索引(又称"下标"(
附录:如果您的端口列表像这样大,您还可以选择从文件中读取端口:
awk 'NR == FNR {ports[$1]; next} $2 in ports' ports.list myfile
或者,如果您将端口保存在字符串中,则使用:
ports='1010 2020 3030 8888 12345'
awk 'NR==FNR{ports[$1]; next} $2 in ports' <(printf '%sn' $ports) myfile
127.0.0.1 1010
127.0.0.1 12345
既然你说了I'd like a succinct way to create a list or array in awk and then test each line against that list
,这里有一种简洁的方法可以在awk中创建一个列表,然后根据该列表测试每一行:
$ awk 'index(",1010,2020,3030,8888,12345,",","$2",")' file
127.0.0.1 1010
127.0.0.1 12345
或者如果您喜欢:
$ awk -v ports='1010,2020,3030,8888,12345' 'index(","ports",",","$2",")' file
127.0.0.1 1010
127.0.0.1 12345
假设有大量端口(测试字符串(要测试,我建议使用两个文件而不是一个字符串进行匹配。
设ports.txt
为端口文件,test.txt
为输入测试文件。Beports.txt类似于以下内容:
1010
2020
3030
8888
12345
然后运行
awk 'NR==FNR{port[$0]=$0} ($2 in a){print}' ports.txt test.txt
这将从第一个文件创建CCD_ 8数组,并在第二个文件中匹配时使用它进行打印。
这个解决方案扩展了anubhava的答案中提出的概念,但使用了您想要的简洁语法。
有关NR==NFR
语法的更多信息,请点击此处。关于可重用性的最后一点注意事项:附加到外部进程,您可能对相同的test.txt
文件运行相同的awk语法,更改ports.txt
文件(例如ports1.txt
、ports2.txt
、portn.txt
…(,以便您可以匹配端口组。
假设您在ports.txt
中有端口,那么您可能可以使用join:
$ cat ports.txt
1010
2020
3030
8888
12345
$ join -12 -o1.1,2.1 <(sort -bk2 myFile.txt) <(sort -b ports.txt)
127.0.0.1 1010
127.0.0.1 12345