ubuntuforums.orgで質問して満足のいく回答が得られなかったため、Ask Ubuntuで再度質問することにしました。回答は非常に詳細なものでなければなりません。具体的には、どれの行が比較される毎回次の 2 つの例では、 uniq を使用して行が印刷されます。
ファイル1.txt:
$ cat -A file1.txt
aaa^Iupc$
b$
c$
aaa^Iztp$
b$
c$
C$
A$
B$
B$
b$
$ sort file1.txt | uniq -f 1
A
aaa upc
aaa ztp
b
そしてfile2.txt:
$ cat -A file2.txt
aaa^Iupc$
b$
c$
aaa^Iztp$
b$
c$
C$
A$
B$
B$
bbb^Ixpz$
$ sort file2.txt | uniq -f 1
A
aaa upc
aaa ztp
b
bbb xpz
c
2 番目の例について混乱しています。大文字の B が最終出力に表示されないのはなぜか理解できません。行と行が隣接している場合、大文字の B の行は印刷されるべきではないでしょうB
かbbb xpz
?
B ---> (empty)
そして
bbb ---> xpz
空の値であり、xpz
両方とも一意であるため、両方の行が印刷される必要があります。それとも、何か見落としているのでしょうか?
答え1
答えはソート順にあります。また、を使用しているときに、指定されたフィールド番号 ( )uniq
より小さいフィールド値が存在する場合、 はフィールド値に何を使用するかにも関係します。N
-f N
ご覧のとおり、ASCII 文字セットを使用しているため、ソート順序は予測可能です。
% sort file.txt
A
aaa upc
aaa ztp
b
b
B
B
bbb xpz
c
c
C
uniq -f 1
ここで、チェック中に各行の最初のフィールド (空白で区切られた) をスキップして一意の行を取得するために、を使用します。
% sort file.txt | uniq -f 1
A
aaa upc
aaa ztp
b
bbb xpz
c
ここで、注目すべき重要な点は、uniq
指定されたフィールド数 (この場合は 1) より少ないフィールド数を持つ行には null 文字列が使用されることです。したがって、フィールド数が 1 つのみの行はすべて、フィールド数が >=2 の他の行と比較すると、他のフィールドに null 文字列があるものとして扱われます。
したがって、sort file2.txt
出力は次のようになります。
b
b
B
B
すべて同じものとして扱われ、 を含む最初の行のみb
が保持されるため、b
出力には が表示されます。
同様に、
c
c
C
最初のものだけがの出力c
に含まれますuniq
。
答え2
このプロセスを実行する際に役立つ表を以下に示します。
----------------+---------------+----------+----------------+
sort | Remove | Adjacent | |
(C locale) | field #1 | match? | Output |
----------------+---------------+----------+----------------+
A | | N* |A |
B | | Y | |
B | | Y | |
C | | Y | |
aaa upc | upc | N |aaa upc |
aaa ztp | ztp | N |aaa ztp |
b | | N |b |
b | | Y | |
bbb xpz | xpz | N |bbb xpz |
c | | N |c |
c | | Y | |
----------------+---------------+----------+----------------+
* the first line has no adjacent above, so is always output