AWK,从一个文件中排除与第二个文件相关的结果

AWK,从一个文件中排除与第二个文件相关的结果,awk,Awk,使用Awk,我能够获得一个带有给定错误号的URL列表: awk '($9 ~ /404/)' /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -rn 漂亮漂亮 但我们希望通过将结果与已知的404URL列表进行匹配来进一步完善它 例如: awk '($9 ~ /404/)' /var/log/nginx/access.log | awk '{print $7} '| sort | uniq -c | so

使用Awk,我能够获得一个带有给定错误号的URL列表:

awk '($9 ~ /404/)' /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -rn
漂亮漂亮

但我们希望通过将结果与已知的404URL列表进行匹配来进一步完善它

例如:

awk '($9 ~ /404/)' /var/log/nginx/access.log | awk '{print  $7} '| sort | uniq -c | sort -k 2 -r |  awk '{print > "/mnt/tmp/404error.txt"}'
今日收益率:

1 /going-out/restaurants/the-current-restaurent.htm
1 /going-out/restaurants/mare.HTML
1 /going-out/report-content/?cid=5
1 /going-out/report-content/?cid=38550
1 /going-out/report-content/?cid=380
后天:

1 /going-out/ru/%d0%bd%d0%be%d1%87%d0%bd%d0%b0%d1%8f-%d0%b6%d0%b8%d0%b7%d0%bd%d1%8c-%d0%bd%d0%b0-%d0%bf%d1%85%d1%83%d0%ba%d0%b5%d1%82%d0%b5/%d1%81%d0%be%d0%b2%d0%b5%d1%82%d1%8b-%d0%bb%d1%8e%d0%b1%d0%b8%d1%82%d0%b5%d0%bb%d1%8f%d0%bc-%d0%bd%d0%be%d1%87%d0%bd%d1%8b%d1%85-%d1%80%d0%b0%d0%b7%d0%b2%d0%bb%d0%b5%d1%87%d0%b5%d0%bd%d0%b8%d0%b9/
1 /going-out/restaurants/the-current-restaurent.htm
1 /going-out/restaurants/mare.HTML
1 /going-out/report-content/?cid=5
1 /going-out/report-content/?cid=38550
1 /going-out/report-content/?cid=380
1 /going-out/report-content/?cid=29968
1 /going-out/report-content/?cid=29823
目标是只拥有新的URL

在这一点上,我迷路了,我知道我可以将第一个文件放入一个数组中,我假设我可以对第二个文件(但在第二个数组中)执行相同的操作,然后可能(不确定awk是否有容量)简单地将它们交叉,并保留不匹配的内容

非常感谢您的帮助。

您可以使用
grep--fixed strings--file=FILEALL FILENEW
comm-23 FILENEW FILEALL
。FILEALL是包含已经找到的URL的文件,FILENEW包含今天找到的页面。对于
comm
,必须对两个文件进行排序

我认为
comm
效率更高,因为我使用了排序文件,但我没有对此进行测试。

您可以使用
grep--fixed strings--file=FILEALL FILENEW
comm-23 FILENEW FILEALL
进行此操作。FILEALL是包含已经找到的URL的文件,FILENEW包含今天找到的页面。对于
comm
,必须对两个文件进行排序


我认为
comm
效率更高,因为我使用了排序文件,但我没有对此进行测试。

因此您有一个文件,其
$9
字段可能与
/404/
匹配。如果是,则要存储第7个字段。然后,计算它们总共出现了多少,但前提是它们以前没有出现在您拥有的文件中

我认为所有这些都可以用这个来完成(未经测试,因为我没有样本输入数据):

这会将包含数据的文件的第二列存储到数组
seen[]
。然后,遍历新文件并存储第7列(如果以前未看到)。最后,它打印计数器


因为它看起来像是一个旧的
awk
版本,不支持数组中的语法
索引
,所以可以使用以下解决方法:

$9 ~ /404/ {for (i in seen) {if (i==$7) next} a[$7]++}
注意:您必须使用非常旧的版本,因为它是在1987年推出的:

awk语言在版本7发布之后有了很大的发展 Unix(1978)和最初普遍制造的新版本 在System V版本3.1(1987)中提供。本节总结了 更改,包括更多详细信息的交叉引用:

for语句外部的表达式“indx in array”(请参阅 参考要素)


因此,您有一个文件,其
$9
字段可能与
/404/
匹配。如果是,则要存储第7个字段。然后,计算它们总共出现了多少,但前提是它们以前没有出现在您拥有的文件中

我认为所有这些都可以用这个来完成(未经测试,因为我没有样本输入数据):

这会将包含数据的文件的第二列存储到数组
seen[]
。然后,遍历新文件并存储第7列(如果以前未看到)。最后,它打印计数器


因为它看起来像是一个旧的
awk
版本,不支持数组中的语法
索引
,所以可以使用以下解决方法:

$9 ~ /404/ {for (i in seen) {if (i==$7) next} a[$7]++}
注意:您必须使用非常旧的版本,因为它是在1987年推出的:

awk语言在版本7发布之后有了很大的发展 Unix(1978)和最初普遍制造的新版本 在System V版本3.1(1987)中提供。本节总结了 更改,包括更多详细信息的交叉引用:

for语句外部的表达式“indx in array”(请参阅 参考要素)


我得出了以下结论:

awk 'BEGIN {
while (getline < "/mnt/tmp/404error.txt") {
A[$1] = $1;
};

while (getline < "/var/log/nginx/access.log") {
if( $9 ~ /404/) 
{
{
exist[$7] = $7 ;
}
{
if ($7 in A) blah += 1; else new[$7];
}
}
}
{
asort(exist);
for(i in exist)
print exist[i] > "/mnt/tmp/404error.txt"
}
{
asorti(new);
for(i in new)
print new[i] > "/mnt/tmp/new404error.txt"
}
}
' | mutt -s "subject" -a /mnt/tmp/new404error.txt -- whoever@mail.net, whatever@mail.net
awk'开始{
而(getline“/mnt/tmp/404error.txt”
}
{
asorti(新);
(我在纽约)
打印新的[i]>“/mnt/tmp/new404error.txt”
}
}
“| mutt-s“subject”-a/mnt/tmp/new404error.txt--whoever@mail.net, whatever@mail.net
这似乎提供了我想要的(几乎)

但我认为它太冗长了,也许你们中的一个天才可以改进它
谢谢

我想到了以下几点:

awk 'BEGIN {
while (getline < "/mnt/tmp/404error.txt") {
A[$1] = $1;
};

while (getline < "/var/log/nginx/access.log") {
if( $9 ~ /404/) 
{
{
exist[$7] = $7 ;
}
{
if ($7 in A) blah += 1; else new[$7];
}
}
}
{
asort(exist);
for(i in exist)
print exist[i] > "/mnt/tmp/404error.txt"
}
{
asorti(new);
for(i in new)
print new[i] > "/mnt/tmp/new404error.txt"
}
}
' | mutt -s "subject" -a /mnt/tmp/new404error.txt -- whoever@mail.net, whatever@mail.net
awk'开始{
而(getline“/mnt/tmp/404error.txt”
}
{
asorti(新);
(我在纽约)
打印新的[i]>“/mnt/tmp/new404error.txt”
}
}
“| mutt-s“subject”-a/mnt/tmp/new404error.txt--whoever@mail.net, whatever@mail.net
这似乎提供了我想要的(几乎)

但我认为它太冗长了,也许你们中的一个天才可以改进它
谢谢

所以您有一个已匹配URL的现有文件,您希望打印那些匹配条件但不在该文件中的URL?或多或少。我有一个带有URL/路径的文件,我们已经检查过了,每周我都从access.log获得一个404的新列表。我想交叉它们,并打印出那些不在第一位的列表(表示新404)。我是法国人,所以我很难解释我的问题如此冗长的原因。所以你有一个URL匹配的现有文件,你想打印那些匹配条件但不在该文件中的文件?或多或少。我有一个带有URL/路径的文件,我们已经检查过了,每周我都从access.log获得一个404的新列表。我想交叉它们,并打印出那些不在第一位的列表(表示新404)。我是法国人,所以很难解释为什么我的问题如此冗长