Bash

將任何長於 n 的行合併為一個,保持該行的任何其他實例的完整性

  • October 14, 2022

我有一個格式如下的域名文件:

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

我想折疊同一行的任何執行 IFF 執行時間長於例如 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)

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,則輸出第二列的值該次數;否則,它會輸出一次。

引用自:https://unix.stackexchange.com/questions/720994