制作一个丑陋的脚本,将一堆主机文件编译成一个大列表。
大多数列表都会有两个 URL 条目,一个有www.
,一个没有,如下所示:
127.0.0.1 facebook.com
127.0.0.1 www.facebook.com
然而,我的一些清单不会像那样加倍,但我希望它们如此。我有很多像这样的分散网址:
127.0.0.1 twitter.com
127.0.0.1 www.facebook.com
127.0.0.1 subdomain.facebook.com
127.0.0.1 tumblr.com
127.0.0.1 www.reddit.com
我想要做的是扫描文件中列出的 URL,以验证所有没有与www.
匹配的行www.
,并且所有带有 a 的行都www.
具有与不带www.
.然后我想将任何缺失的行附加到列表中,这样我的列表将如下所示:
127.0.0.1 twitter.com
127.0.0.1 www.twitter.com
127.0.0.1 facebook.com
127.0.0.1 subdomain.facebook.com
127.0.0.1 www.facebook.com
127.0.0.1 www.subdomain.facebook.com
127.0.0.1 tumblr.com
127.0.0.1 www.tumblr.com
127.0.0.1 reddit.com
127.0.0.1 www.reddit.com
它不需要按顺序排列,我可以将所有缺失的行附加到文件末尾,因为我sort -u
作为最后一步运行。
答案1
您可以跳过检查并添加配对行,然后将输出通过管道传输到sort -u
:
sed '/ www./{ # if line matches www.
h # copy it over the hold buffer
s// / # remove the www. part
G # append the original line to the modified one
}
//!{ # if line doesn't match www.
h # copy it over the hold buffer
s/ / www./ # add the www. part
G # append the original line to the modified one
}
' infile | sort -u
这假设两列(IP 和 URL)由空格分隔。如果需要,调整正则表达式。
或者,使用zsh
,您可以读取数组中的行,删除www.
存在的部分并将结果存储在唯一元素的数组中,然后将每个元素打印两次,一次按原样打印,一次添加www.
添加的部分:
mylist=(${(f)"$(<infile)"})
for i (${(u)mylist[@]/ www./ }) printf '%s\n' ${i} ${i/ / www.}
答案2
您可以使用以下awk
脚本:
脚本.awk:
{
gsub("www.", "", $2)
address[$2]
}
END{
for (item in address){
print("127.0.0.1", item)
print("127.0.0.1", "www." item)
}
}
调用它
awk -f script.awk input
它www.
从所有条目的开头删除,然后填充一个数组(没有值)。如果该值已经存在,它将简单地覆盖它,因此您不必关心重复项。最后,我们打印数组的内容,一次按原样打印,一次带前缀www.
。