awk-如果域已经匹配,则跳过子域的行

时间:2018-10-01 16:00:44

标签: bash awk

让我们假设-已经有一个已经排序的域列表,例如:

tld.aa.
tld.aa.do.notshowup.0
tld.aa.do.notshowup.0.1
tld.aa.do.notshowup.0.1.1
tld.aa.do.notshowup.too
tld.bb.showup
tld.aaaaa.showup
tld.xxxxx.
tld.xxxxx.donotshowup
tld.yougettheidea.dontyou
tld.yougettheidea.dontyou.thankyou

后来成为黑名单。

根据特定要求-所有行尾均带有'。'表明 该特定域的所有更深的子域都不应出现 然后在黑名单本身中...因此示例的所需输出 以上将/应该是:

tld.aa.
tld.bb.showup
tld.aaaaa.showup
tld.xxxxx.
tld.yougettheidea.dontyou
tld.yougettheidea.dontyou.thankyou

我目前在一个循环中运行此程序(纯bash +大量使用bash内置函数来加快处理速度)...但是作为列表 增长,现在大约要处理562k条目。

AWK(也许是sed)这样做不容易-任何帮助都是 非常感谢(我已经在awk中尝试了一些操作,但是由于某种原因无法显示我想要的内容...)。

谢谢!

1 个答案:

答案 0 :(得分:3)

如果.行始终位于要忽略的行之前,则该awk应该这样做:

$ awk '{for (i in a) if (index($0,i) == 1) next}/\.$/{a[$0]=1}1' file
tld.aa.
tld.bb.showup
tld.aaaaa.showup
tld.xxxxx.
tld.yougettheidea.dontyou
tld.yougettheidea.dontyou.thankyou
  • /\.$/{a[$0]=1}将带有结尾点的行添加到数组中。
  • {for (i in a) if (index($0,i) == 1) next}在这些索引条目之一中搜索当前行,如果找到则跳过进一步的处理(next)。

如果文件按字母顺序排序,并且没有子域以点结尾,那么您甚至不需要@Corentin Limier建议的数组:

awk 'a{if (index($0,a) == 1) next}/\.$/{a=$0}1' file