假设:
- csv 文件(有 2 列:域名 + ip 地址)使用逗号 (
,) 作为分隔符(示例数据中未显示,但 OP 在评论中提到了这一点)
- 没有提到按任何特定顺序对最终输出进行排序的任何要求,因此我将以与以下相同的顺序打印输出:
- ips 出现在第一个文件中
- 域地址出现在 csv 文件中
- 没有为第一个文件提供示例,所以我假设每行有一个 ip 地址
- 我不会担心 IP 地址在第一个文件中出现多次的可能性(即,每次 IP 地址出现在第一个文件中时,我们将重复打印相同的匹配域名文件)
- 任何一个文件中没有另一个文件“匹配”的条目都不会显示在最终输出中
样本数据:
$ cat domain.dat
example.com,1.1.1.1
example3.com,3.4.5.6
example5.com,11.12.13.14
exampleX.com,99.99.99.99 # no matches in ip.dat
example2.com,1.1.1.1
example4.com,11.12.13.14
$ cat ip.dat
1.1.1.1
2.2.2.2 # no matches in domain.dat
3.4.5.6
7.8.9.10 # no matches in domain.dat
11.12.13.14
1.1.1.1 # repeat of an ip address
此awk 解决方案首先处理domain.dat 以填充数组(domains[<ipaddress>]=<domainaddress>[,<domainaddress]*),然后处理ip.dat 以确定要打印到标准输出的域地址:
awk -F "," '
# first file: keep track of the longest domain address; to be used by printf
NR==FNR { if (length($1) > maxlen) { maxlen=length($1) } }
# first file: if the ip address is already an index in our array then append the current domain address to the array element; skip to next of input
(NR==FNR) && ($2 in domains) { domains[$2]=domains[$2]","$1 ; next }
# first file: first time we have seen this ip address so create a new array element, using the ip address as the array index; skip to next line of input
NR==FNR { domains[$2]=$1 ; next}
# second file: if the ip address is an index in our array ...
# split the domain address(es), delimited by comma, into a new array named "arr" ...
( $1 in domains ) { split(domains[$1],arr,",")
# set the output line suffix to the ip address
sfx=$1
# loop through our domain addresses, appending the ip address to the end of the first line; after we print the first domain
# address + ip address, reset suffix to the empty string so successive printfs only display the domain address;
# the "*" in the format string says to read the numeric format from the input parameters - "maxlen" in this case
for (i in arr) { printf "%-*s %s\n",maxlen,arr[i],sfx ; sfx="" }
}
' domain.dat ip.dat
注意:嵌入的 cmets 可以移除以减少混乱。
以上运行结果:
example.com 1.1.1.1
example2.com
example3.com 3.4.5.6
example5.com 11.12.13.14 # example5.com comes before example4.com in domain.dat
example4.com
example.com 1.1.1.1 # repeated because 1.1.1.1 was repeated in ip.dat
example2.com