我希望能够使用awk
代替while循环,以从输入字符串中删除子域(如果它也包含主域)。
源文件:
1234.f.dsfsd.test.com
abc.test.com
ad.sdk.kaffnet.com
amazon.co.uk
analytics.test.dailymail.co.uk
bbc.co.uk
bbc.test.com
dailymail.co.uk
kaffnet.com
sdk.kaffnet.com
sub.test.bbc.co.uk
t.dailymail.co.uk
test.amazon.co.uk
test.bbc.co.uk
test.com
test.dailymail.co.uk
所需的输出:
amazon.co.uk
bbc.co.uk
dailymail.co.uk
kaffnet.com
test.com
解决方案:@EdMorton
答案 0 :(得分:4)
检查域的最后一部分,看看其中哪一个是最短的字符串:
BEGIN{FS="."}
{
ind=$(NF-1) FS $NF;
if (!(ind in size) || (size[ind] > length)) {
size[ind]=length # check the minimum size for this domain
domain[ind]=$0 # store the string with the minimum size on this domain
}
}
END {for (ind in domain) print domain[ind]}
单线:
$ awk 'BEGIN{FS="."} {ind=$(NF-1) FS $NF; if (!(ind in size) || (size[ind] > length)) { size[ind]=length; domain[ind]=$0}} END {for (ind in domain) print domain[ind]}' file
test.com
bbc.co.uk
只需使用字段分隔符并将其设置为点即可。这样,只需将倒数第二个和倒数第二个存储为字符串,然后检查您发现多少个不同的问题即可。
$ awk -F. '{a[$(NF-1) FS $NF]} END{for (i in a) print i}' file
test.com
这是如何工作的? a[]
是一个数组,我们一直在其中添加索引。索引是用倒数第二个字段,一个点和最后一个字段定义的。这样,任何新的bla.test.com
仍将具有相同的索引,并且不会在数组中添加额外的信息。
使用其他输入:
$ cat file
1234.f.dsfsd.test.com
abc.test.com
bbc.test.com
test.com
bla.com
another.bla.com
$ awk -F. '{a[$(NF-1) FS $NF]} END{for (i in a) print i}' file
test.com
bla.com
答案 1 :(得分:2)
基于新要求和新示例输入文件的新答案:
$ cat tst.awk
{ doms[$0] }
END {
for (domA in doms) {
hasSubDom = 0
for (domB in doms) {
if ( index(domA,domB ".") == 1 ) {
hasSubDom = 1
}
}
if ( !hasSubDom ) {
print domA
}
}
}
$ rev file | awk -f tst.awk | rev
bbc.co.uk
dailymail.co.uk
amazon.co.uk
kaffnet.com
test.com
$ rev file | sort |
awk -F'.' 'index($0,prev FS)!=1{ print; prev=$1 FS $2 }' |
rev
bbc.co.uk
test.com
以上只是实现您在问题中描述的算法。它反转每一行的字符,然后像您已经在做的那样对结果进行排序,然后如果前一行是foo.bar.stuff
,则prev
是foo.bar
,因此如果当前行是{ {1}},然后调用索引将发现foo.bar.otherstuff
(注意最后的foo.bar.
-将最后的.
添加到比较中很重要,这样.
不会不会错误地匹配foo.bar
)确实发生在当前行的开头(索引位置1),因此我们不会打印该行,而foo.barristers.wig
将保持原样。另一方面,如果当前行是prev
,则在该行的开头不会出现my.sharona.song
(prev
),因此该行将被打印并且foo.bar
设置为prev
。最后,它只是将每条输出线上的字符恢复为原始顺序。
答案 2 :(得分:1)
如果使用<div class="page">
<div class="oe_structure"/>
<div class="col-xs-6 pull-left">
<h2 style="color:red">
<span>Plan Order :
<span style="color:Red" t-field='doc.name'/>
</span>
</h2>
</div>
<div colspan="4" class="col-xs-6 text-right">
<span>
<img t-att-src="'/report/barcode/?type=%s&value=%s&width=%s&height=%s' % ('Code128', doc.name, 500, 50)"
style="width:100%;height:50px"/>
</span>
</div>
运算符构建变量,则可以在awk中测试动态正则表达式
~
Example(使用tac和rev来促进还原)
您的方法的问题在于,由于仅显示前一行,因此您至少需要2行用于该域,但是如果您没有前一行?如果您的域总是至少包含2行,那么对您来说这可能不是问题。
答案 3 :(得分:1)
对于它的价值而言,这是一个不需要重新输入和排序就可以工作的版本。
awk -F. 'BEGIN {
SLDs = "co.uk,gov.uk,add.others" # general-use second-level domains we recognize
split(SLDs, slds, /,/);
for (i in slds) slds[slds[i]] = 1
}
/./ {
tld = $(NF-1) "." $(NF)
if (NF > 2 && tld in slds) tld = $(NF-2) "." tld
lines[NR] = $0
tlds[NR] = tld
if (tld == $0) existing_tlds[tld] = 1
}
END {
for (i = 1; i <= length(lines); i++) {
line = lines[i]; tld = tlds[i]
if (!(tld in existing_tlds) || tld == line) print(line)
}
}' input_file
这将遍历文件并构建一个现有TLD阵列。在END
块中,仅当它是TLD本身 或该数组中不存在其TLD时,才打印一行。
input_file
是
1234.f.dsfsd.test.com
abc.test.com
amazon.co.uk
bbc.co.uk
bbc.test.com
sub.test.bbc.co.uk
test.amazon.co.uk
test.bbc.co.uk
test.com
它打印
amazon.co.uk
bbc.co.uk
test.com