从文件中复制纯文本行并将其附加到带有中线前缀的同一文件中或删除中线前缀

从文件中复制纯文本行并将其附加到带有中线前缀的同一文件中或删除中线前缀

制作一个丑陋的脚本,将一堆主机文件编译成一个大列表。

大多数列表都会有两个 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.

相关内容