Intelligente Lösungen
in neuer Dimension

Linux - Shell: Doppelte Zeilen entfernen aus einer Datei ohne Umsortieren

Manchmal stelle ich fest, dass Dateien doppelte Zeilen enthalten die nicht vorhanden sein sollten. Wenn die Sortierung der Zeilen keine Rolle spielt, so kann man die doppelten Zeilen einfach entfernen mit:

1
2
sort -u (dateiname) >(dateiname)~
mv (dateiname)~ (dateiname)

Ein wenig komplizierter wird es, wenn man die Sortierung der Zeilen beibehalten möchte!

TLDR

1
2
cat -n (dateiname)|sort -u -k 2|sort -n|cut -f 2- >(dateiname)~
mv (dateiname)~ (dateiname)

Test

Ausgangsdatei – clamd.conf:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#To reconfigure clamd run #dpkg-reconfigure clamav-daemon
#Please read /usr/share/doc/clamav-daemon/README.Debian.gz for details
LocalSocket /var/run/clamav/clamd.ctl
FixStaleSocket true
LocalSocketGroup clamav
LocalSocketMode 666
# TemporaryDirectory is not set to its default /tmp here to make overriding
# the default with environment variables TMPDIR/TMP/TEMP possible
User clamav
ScanMail true
...
OnAccessExcludeUname clamav
User clamav
User clamav
User clamav

Korrekturkommandos:

1
2
cat -n clamd.conf|sort -u -k 2|sort -n|cut -f 2- >clamd.conf~
mv clamd.conf~ clamd.conf

Ergebnisdatei:

1
2
3
4
5
6
7
8
9
10
11
12
#To reconfigure clamd run #dpkg-reconfigure clamav-daemon
#Please read /usr/share/doc/clamav-daemon/README.Debian.gz for details
LocalSocket /var/run/clamav/clamd.ctl
FixStaleSocket true
LocalSocketGroup clamav
LocalSocketMode 666
# TemporaryDirectory is not set to its default /tmp here to make overriding
# the default with environment variables TMPDIR/TMP/TEMP possible
User clamav
ScanMail true
...
OnAccessExcludeUname clamav

Funktionsweise

Ausgangspunkt

Ausgangspunkt ist eine Text-Datei, bspw. mit diesem Inhalt:

1
2
3
4
5
6
7
8
Dies ist Uli's Text-Datei!
Sie ist toll!
Warum das?
Sie ist toll!
Ende
Sie ist toll!
Ende  1
Ende  2

Die beiden Zeilen mit “Ende 1” und “Ende 2” enthalten jeweils ein Tabulator-Zeichen zwischen “Ende” und der Ziffer!

Zeilennummern hinzufügen

Mit dem Kommando cat -n (dateiname) werden Zeilennummern vorangestellt. Diese brauchen wir, um später wieder die Original-Reihenfolge herzustellen!

cat -n (dateiname):

1
2
3
4
5
6
7
8
1    Dies ist Uli's Text-Datei!
     2    Sie ist toll!
     3    Warum das?
     4    Sie ist toll!
     5    Ende
     6    Sie ist toll!
     7    Ende    1
     8    Ende    2

In der Darstellung kann man nicht erkennen, dass zwischen den Zeilennummern und den Textzeilen keine Leerzeichen sondern ein Tabulatorzeichen steht. Das erledigt cat -n per Standard so und ist für uns vorteilhaft! Mit Leerzeichen funktionieren die nachfolgenden Kommandos nicht!

Sortieren beginnend mit Feld2 und löschen von doppelten Werten

Mit dem Kommando sort -u -k 2 wird beginnend mit Feld2 (“-k 2”) sortiert. Dabei wird die Zeilennummer übersprungen und nicht berücksichtigt! Zusätzlich werden Doppelwerte übersprungen (“-u”).

cat -n (dateiname)|sort -u -k 2:

1
2
3
4
5
6
1    Dies ist Uli's Text-Datei!
     5    Ende
     7    Ende    1
     8    Ende    2
     2    Sie ist toll!
     3    Warum das?

Wiederherstellung der Ursprungssortierung

Die ursprüngliche Sortierung wird wiederhergestellt durch sort -n. Dabei werden alle Zeilen “numerisch” sortiert, also nach Zeilennummer.

cat -n (dateiname)|sort -u -k 2|sort -n:

1
2
3
4
5
6
1    Dies ist Uli's Text-Datei!
     2    Sie ist toll!
     3    Warum das?
     5    Ende
     7    Ende    1
     8    Ende    2

Entfernen der Zeilennummern

Zuletzt müssen die Zeilennummern entfernt werden mit cut -f 2-.

cat -n (dateiname)|sort -u -k 2|sort -n|cut -f 2-:

1
2
3
4
5
6
Dies ist Uli's Text-Datei!
Sie ist toll!
Warum das?
Ende
Ende  1
Ende  2

Historie

  • 2023-08-27: Erste Version