我有一个域名文件,格式如下:
www.mozilla.org
www.mozilla.org
www.mozilla.org
www.mozilla.org
www.google.com
www.google.com
www.rust-lang.org
www.google.com
www.google.com
www.google.com
www.google.com
我想折叠同一行的任何运行,如果运行时间长于例如 4。这将为我提供以下输出数据:
www.mozilla.org
www.google.com
www.google.com
www.rust-lang.org
www.google.com
我希望在 Bash 中做到这一点,我得到的最接近的是 Python 中的这个 5 分钟的简单解决方案:
inp = """www.mozilla.org
www.mozilla.org
www.mozilla.org
www.mozilla.org
www.google.com
www.google.com
www.rust-lang.org
www.google.com
www.google.com
www.google.com
www.google.com"""
def collapse(n, inp):
prev = ""
output = []
cnt = 0
for line in inp.split('\n'):
if line == prev:
cnt += 1
if line != prev:
if cnt >= n-1:
output = output[:-cnt]
cnt = 0
prev = line
output.append(line)
#last set of lines is an edgecase
if cnt > n-2:
output = output[:-cnt]
print('\n'.join(output))
collapse(4, inp)
答案1
用于uniq -c
计算运行的长度,然后awk
根据这些计数输出适当次数的数据:
$ uniq -c file | awk '$1 >= 4 { $1 = 1 } { for (i = 1; i <= $1; ++i) print $2 }'
www.mozilla.org
www.google.com
www.google.com
www.rust-lang.org
www.google.com
该uniq -c
命令将使用示例数据输出以下行:
4 www.mozilla.org
2 www.google.com
1 www.rust-lang.org
4 www.google.com
该awk
命令作用于第一列中的数字,如果数字小于 4,则输出第二列的值;否则,它会输出一次。