Die Verwendung von uniq -f 1 führt zu unerwarteten Ergebnissen

Die Verwendung von uniq -f 1 führt zu unerwarteten Ergebnissen

Nachdem ich eine Frage auf ubuntuforums.org gestellt und keine zufriedenstellende Antwort erhalten habe, habe ich beschlossen, die Frage hier auf Ask Ubuntu noch einmal zu stellen. Ich brauche eine sehr detaillierte Antwort. Insbesondere muss ich wissenwelcheLinien werden verglichenjedes MalFür die folgenden beiden Beispiele wird eine Zeile mit uniq gedruckt:

Datei1.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

und Datei2.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

Das zweite Beispiel verwirrt mich. Ich verstehe nicht, warum das große B nicht in der Endausgabe erscheint. Sollte die Zeile mit dem großen B nicht gedruckt werden, wenn die Zeilen Bund bbb xpznebeneinander liegen? Wenn:

B ---> (empty)

Und

bbb ---> xpz

ein leerer Wert und xpzsind beide eindeutig, also sollten beide Zeilen gedruckt werden. Oder übersehe ich etwas?

Antwort1

Die Antwort liegt in der Sortierreihenfolge und was uniqfür einen Feldwert verwendet wird, wenn bei der Verwendung weniger als die angegebene Feldnummer ( N) vorhanden ist -f N.

Wie Sie sehen, verwenden Sie ASCII-Zeichensätze, sodass die Sortierreihenfolge weitgehend vorhersehbar ist:

% sort file.txt            
A
aaa upc
aaa ztp
b
b
B
B
bbb xpz
c
c
C

Verwenden wir nun das Verfahren, uniq -f 1um eindeutige Zeilen zu erhalten, indem wir beim Prüfen das (durch Leerzeichen getrennte) erste Feld jeder Zeile überspringen:

% sort file.txt | uniq -f 1
A
aaa upc
aaa ztp
b
bbb xpz
c

Wichtig zu beachten ist nun, dass uniqfür Zeilen mit weniger als den genannten Feldern (in diesem Fall 1) ein Nullstring verwendet wird. Alle Zeilen mit nur einem Feld werden daher beim Vergleich mit anderen Zeilen mit >= 2 Feldern so behandelt, als hätten sie Nullstrings für andere Felder.

sort file2.txtAus der Ausgabe ergibt sich also :

b
b
B
B

würden alle gleich behandelt und nur die erste Zeile, die enthält, bwürde beibehalten, daher hätten Sie ein bin der Ausgabe.

Ebenso von:

c
c
C

nur der erste würde in der Ausgabe clanden .uniq

Antwort2

Hier ist eine Tabelle, die Ihnen bei der Durchführung des Vorgangs helfen kann:

----------------+---------------+----------+----------------+
    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

verwandte Informationen