staging.inyokaproject.org

sed löschen von gleichen Zeilen in einer von zwei Dateien geht nicht

Status: Gelöst | Ubuntu-Version: Ubuntu 15.10 (Wily Werewolf)
Antworten |

petra_78

Anmeldungsdatum:
25. Juni 2016

Beiträge: Zähle...

und wieder hab ich lange probiert und es will wieder nicht klappen:

Ich habe zwei unsortierte Pfadlisten in der einen sind mehr Pfade enthalten als in der zweiten. Alles was in der zweiten steht steht auch in der ersten. Ich möchte aus der ersten alles löschen was auch in der zweiten steht. So hätte ich eine Liste mit Zeilen die nur in der ersten aber nicht in der zweiten Liste stehen.

Für kleine Listen ging das hier (bis auf die Zeilen mit Leerzeichen drin - aber die stehen eh nur in der ersten Liste):

#!/bin/bash

while read zeile

do

sed -i '\#'$zeile'#d' ./Liste_mit_Pfadangaben

done < ./Liste_mit_Vergleichspfaden

bei 58000 Zeilen dauert das schon Stunden und die Liste mit Pfadangaben ändert sich nicht.

Danach kann ich dann die Liste benutzen um diese Dateien alle zu löschen.

Was mach ich falsch oder wie geht das einfacher?

Mit diff (und sortierten Listen) kam ich auch nicht weiter.

Dank schon mal für die Hilfe.

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wenn es nichts ausmacht, dass die Listen vorher sortiert werden, dann kannst Du dafür ganz stur comm benutzen:

track@track:~$ head -20 liste_[12]*
==> liste_1.txt <==
Hallo welt!-
123334-
Tennis -
214324-
Fussball -
134342-
Hockey-
24-
Golf -
23424-
Handball- 
23424-

==> liste_2.txt <==
Hallo Welt!-
Tennis-
fussball -
Hockey-
Golf-
Handball -
Curling-
track@track:~$ comm  -23 <(sort liste_1*)  <(sort liste_2*)
123334-
134342-
214324-
23424-
23424-
24-
Fussball -
Golf -
Hallo welt!-
Handball- 
Tennis - 

Sonst wäre das etwas, das sehr schön mit einem assoziativen Array geht, z.B. unter awk:

track@track:~$ awk 'ARGIND==1 {v[$0]=1}  ARGIND==2 {if(! v[$0]) print}'  liste_2* liste_1*
Hallo welt!-
123334-
Tennis -
214324-
Fussball -
134342-
24-
Golf -
23424-
Handball- 
23424- 

Dann bleibt dabei auch die Reihenfolge erhalten.

Sowas mit der Bash nachzubilden geht ganz sicher auch, wäre mir aber ehrlich gesagt zu mühsam.

Bei Deinem Skript löscht Du die "Falschen" einzeln nacheinander, und startest jedes Mal sed dafür ...
Das kostet natürlich etwas Zeit, müsste aber eigentlich gehen.

Du hast allerdings die Variable $zeile nicht "gequotet". Das ist nicht gut.

Wenn Du handwerklich sauber bleibst, läuft Dein Skript eigentlich auch:

1
2
3
4
5
6
#!/bin/bash

cp  liste_1* liste_3
while read zeile; do
	sed -i "\#$zeile#d" liste_3
done < liste_2*

LG,

track

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

petra_78 schrieb:

Ich habe zwei unsortierte Pfadlisten in der einen sind mehr Pfade enthalten als in der zweiten. Alles was in der zweiten steht steht auch in der ersten. Ich möchte aus der ersten alles löschen was auch in der zweiten steht. So hätte ich eine Liste mit Zeilen die nur in der ersten aber nicht in der zweiten Liste stehen.

1
fgrep -vxf zweite erste >erste.kopie

petra_78

(Themenstarter)

Anmeldungsdatum:
25. Juni 2016

Beiträge: 5

Danke rklm!

Und so schön kurz ... und sehr schnell in der Ausführung (keine drei Sekunden!)

Antworten |