将任何长度超过 n 的行折叠成一行,保持该行的任何其他实例的完整性

将任何长度超过 n 的行折叠成一行,保持该行的任何其他实例的完整性

我有一个域名文件,格式如下:

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,则输出第二列的值;否则,它会输出一次。

相关内容