staging.inyokaproject.org

Inhalt von Variablen vergleichen mit "diff"

Status: Gelöst | Ubuntu-Version: Xubuntu 22.04 (Jammy Jellyfish)
Antworten |

Fried-rich

Anmeldungsdatum:
2. Mai 2013

Beiträge: 1162

Hallo,

das CLI-Tool "diff" arbeitet irgendwie nicht wie ich mir das vorstelle. Ich lese den Inhalt aus einer Datenbank aus und vergleiche sie mit dem Inhalt den ich mit "find" ausgelesen habe. Beides liegt in einer Variablen vor. Der Aufrug sieht so aus:

diff -y --suppress-common-lines <(echo "$episode_list_filesystem") <(echo "$episode_list_database")

-y benutze ich wegen der netten Tabellenansicht, --suppress-common-lines um gleiche Zeilen auszublenden. Angenommen die Variablen haben den Inhalt:

/media/data/datei1a.ext
/media/data/datei3.ext

und

/media/data/datei1.ext
/media/data/datei2.ext
/media/data/datei3a.ext

Dann gibt mir diff aus:

/media/data/datei1a.ext		      |	/media/data/datei1.ext
				      >	/media/data/datei2.ext
/media/data/datei3.ext		      |	/media/data/datei3a.ext

So richtig schlüssig ist mir icht wieso diff erst die Zeile 1 (datei1a und datei1) vergleicht, dann aber erkennt, dass datei2 in der Variable 1 fehlt (anstatt jeweils die zweiten Zeilen [datei3 und datei2] zu vergleichen) und dann wieder die 3. Zeile vergleicht. Wenn diff wirklich zeilenweise durchgeht müsste es so aussehen:

/media/data/datei1a.ext		      |	/media/data/datei1.ext
/media/data/datei3.ext	              |	/media/data/datei2.ext
		                      >	/media/data/datei3a.ext

Was ich suche wäre diese Ausgabe:

/media/data/datei1a.ext		      >
                                      <	/media/data/datei1.ext
/media/data/datei3.ext	              >
                                      < /media/data/datei2.ext
		                      <	/media/data/datei3a.ext

So dass man genau erkannt was in Variable 1 vorhanden ist und in Variable 2 nicht und umgedreht.

Falls keiner ein Tool kennt, das genau das macht würde mir nur einfallen Variable 1 zeilenweise einzulesen, zu prüfen ob die Zeile in Variable 2 vorkommt und wenn ja, die Zeile aus Variable 1 und 2 zu löschen. Dann das gleiche mit den (übrig gebliebenen) Zeilen aus Variable 2 mit den (übrig gebliebenen) aus Variable 1. Was aber recht aufwendig wäre.

Doc_Symbiosis

Avatar von Doc_Symbiosis

Anmeldungsdatum:
11. Oktober 2006

Beiträge: 4453

Schau Dir vielleicht mal Textdateien vergleichen (Abschnitt „comm“) an.

Da muss man nur drauf achten, dass die Listen sortiert vorliegen sollten.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Man könnte das mit Sets machen - das lässt sich z.B. in Python recht bequem abbilden (nur die Reihenfolge geht dabei verloren):

1
2
3
4
5
6
7
8
#!/usr/bin/env python3
import sys

set_a, set_b = (set(arg.splitlines()) for arg in sys.argv[1:3])
only_in_a = set_a - set_b
only_in_b = set_b - set_a
print(*(f"{e: <37} >" for e in sorted(only_in_a )), sep='\n')
print(*(f"{' ': <37} < {e}" for e in sorted(only_in_b)), sep='\n')
python show_diff.py "$episode_list_filesystem" "$episode_list_database"
/media/data/datei1a.ext               >
/media/data/datei3.ext                >
                                      < /media/data/datei1.ext               
                                      < /media/data/datei2.ext               
                                      < /media/data/datei3a.ext  

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

Fried-rich schrieb:

So richtig schlüssig ist mir icht wieso diff erst die Zeile 1 (datei1a und datei1) vergleicht, dann aber erkennt, dass datei2 in der Variable 1 fehlt (anstatt jeweils die zweiten Zeilen [datei3 und datei2] zu vergleichen) und dann wieder die 3. Zeile vergleicht. Wenn diff wirklich zeilenweise durchgeht müsste es so aussehen:

/media/data/datei1a.ext		      |	/media/data/datei1.ext
/media/data/datei3.ext	              |	/media/data/datei2.ext
		                      >	/media/data/datei3a.ext

Nicht unbedingt. diff ist frei darin, welche der geänderten Zeilen es als "eingeschoben" betrachtet, weil es dafür kein hartes Kriterium gibt. Vermutlich erkennt er den gemeinsamen Präfix "/media/data/datei3", der länger ist als "/media/data/datei" (Gemeinsamkeit mit ".../datei2.txt") und schließt daraus, dass "/media/data/datei3a.ext" aus "/media/data/datei3.ext" entstanden ist und gibt deswegen diese beiden in einer Zeile aus.

Was ich suche wäre diese Ausgabe: [...] So dass man genau erkannt was in Variable 1 vorhanden ist und in Variable 2 nicht und umgedreht.

Naja, Du kannst ja "--suppress-common-lines" weglassen, was es dem Menschen etwas leichter macht. Oder Du benutzt eines der anderen diff-Formate. Ich nehme am liebsten "-U", weil dann Blöcke von geänderten Zeilen zusammen dargestellt werden.

Wenn Du uns mehr über den Use Case verrätst, können wir vielleicht auch mit zielgenaueren Lösungen um die Ecke kommen.

Antworten |