Awk

如果其他行以目前行開頭,則刪除行(按列)

  • December 18, 2019

我有以下製表符分隔格式的文件 input.txt:

aaaa    bbbb
aaaa    bbbb    c
aaaa    bbbb    c   dd
aaaa    bbbb    cc
aaaa    bbbb    x
aaaa    bbbb    xx
dddd    eeee
dddd    eeee    f
dddd    eeee    f   g
dddd    eeee    fe
h   ii  j

對於每一行,檢查是否有另一行已經包含前導列。如果是這樣,請刪除該行。否則保留它。讓我們看一下這個例子。

  • 第一行被刪除,因為另一行有一個附加列,其第一列是相同的:第二行。在這種情況下,刪除第一行並保留第二行。
  • 第二行被刪除,因為另一行有一個附加列,其第一列相同:第三行。在這種情況下,刪除第二行並保留第三行。
  • 第三行沒有被刪除,因為沒有其他行的第一列相同。在這種情況下,保留第三行。

等等等等。輸出文件應該是:

aaaa    bbbb    c   dd
aaaa    bbbb    cc
aaaa    bbbb    x
aaaa    bbbb    xx
dddd    eeee    f   g
dddd    eeee    fe
h   ii  j

也許我們可以找到一個可以流暢執行數百萬行的解決方案。

這只是對輸入進行反向排序,因此“foobar”出現在“foo”之前,然後如果它是從每個字元的第一個字元開始的前一行(foobar)的子字元串,則不列印目前行(foo)。

$ sort -r file | awk 'index(prev FS,$0 FS) != 1; {prev=$0}'
h   ii  j
dddd    eeee    fe
dddd    eeee    f   g
aaaa    bbbb    xx
aaaa    bbbb    x
aaaa    bbbb    cc
aaaa    bbbb    c   dd

如果輸出順序對您很重要,有辦法解決這個問題,例如:

$ cat -n file | sort -k2r |
   awk '{orig=$0; $1=""} index(prev FS,$0 FS) != 1{print orig} {prev=$0}' |
   sort -n | cut -f2-
aaaa    bbbb    c   dd
aaaa    bbbb    cc
aaaa    bbbb    x
aaaa    bbbb    xx
dddd    eeee    f   g
dddd    eeee    fe
h   ii  j

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