打印文件中没有重复项的行并保留排序顺序 linux

Sye*_*mil 11 awk uniq

我有以下文件:

2
1
4
3
2
1
Run Code Online (Sandbox Code Playgroud)

我想要这样的输出(没有任何重复项并保留顺序的唯一行):

4
3
Run Code Online (Sandbox Code Playgroud)

我尝试过sort file.txt | uniq -u它有效,但输出已排序:

3
4
Run Code Online (Sandbox Code Playgroud)

我尝试awk '!x[$0]++' file.txt保持顺序,但它会打印一次所有值:

2
1
4
3
Run Code Online (Sandbox Code Playgroud)

mar*_*rkp 14

有几个想法可供选择:

a)读取输入文件两次:

awk '
FNR==NR         { counts[$0]++; next }  # 1st pass: keep count
counts[$0] == 1                         # 2nd pass: print rows with count == 1
' file.txt file.txt
Run Code Online (Sandbox Code Playgroud)

b)读取输入文件一次:

awk '
    { lines[NR] = $0                    # maintain ordering of rows
      counts[$0]++
    }
END { for ( i=1;i<=NR;i++ )             # run thru the indices of the lines[] array and ...
          if ( counts[lines[i]] == 1 )  # if the associated count == 1 then ...
             print lines[i]             # print the array entry to stdout
    }
' file.txt
Run Code Online (Sandbox Code Playgroud)

这两者都会生成:

4
3
Run Code Online (Sandbox Code Playgroud)


pmf*_*pmf 10

我尝试过sort file.txt | uniq -u它有效,但输出已排序

grep -f您可以获取该输出,并将其用作原始文件上的换行符分隔模式列表。用于-Fx将模式视为整行固定字符串(而不是正则表达式)。

sort file.txt | uniq -u | grep -Fxf- file.txt
Run Code Online (Sandbox Code Playgroud)
4
3
Run Code Online (Sandbox Code Playgroud)


daw*_*awg 5

这是一个 Ruby 来做到这一点:

ruby -lne 'BEGIN{cnt=Hash.new {|h,k| h[k] = 0} } 
cnt[$_]+=1
END{puts cnt.select{|k,v| v==1}.keys.join("\n") }
' file 
Run Code Online (Sandbox Code Playgroud)

印刷:

4
3
Run Code Online (Sandbox Code Playgroud)

或者,在一次读取文件中:

ruby -e 'puts $<.read.split(/\R+/).
            group_by{|x| x}.select{|k,v| v.length==1}.keys.join("\n")
' file 
# same output
Run Code Online (Sandbox Code Playgroud)

与 awk 不同,Ruby 关联数组维护插入顺序。

如果你想要一张通行证,awk你可以这样做:

awk 'BEGIN{OFS="\t"}
{ if (seen[$0]++) delete order[$0]; else order[$0]=FNR } 
END { for ( e in order ) print order[e], e } ' file | sort -nk 1,1 | cut -f2-
# same output
Run Code Online (Sandbox Code Playgroud)

(感谢 Ed Morton 提供了更好的 awk!)