View previous topic :: View next topic |
Author |
Message |
3PO Veteran
Joined: 26 Nov 2006 Posts: 1110 Location: Schwabenländle
|
Posted: Sun Feb 01, 2009 3:31 pm Post subject: [bash] Wie Dateien bedingt zusammenführen? |
|
|
Hallo Zusammen,
Ich möchte z.B. den Inhalt von abc.foo in xyz.foo einfügen.
So weit so gut, dass das mit cat geht weis ich, aber ich möchte nun, das abc.foo NUR dann eingefügt wird, wenn die Einträge in xyz.foo nicht existieren, bzw. nur die Einträge übernommen werden, die noch nícht in der xyz.foo stehen.
Gib es da eine einfache Lösung, die ich ein Script übernehmen könnte? |
|
Back to top |
|
|
artbody Guru
Joined: 15 Sep 2006 Posts: 494 Location: LB
|
Posted: Sun Feb 01, 2009 3:59 pm Post subject: |
|
|
grep eventuell
Code: | zcat /proc/config.gz | grep -i v4l |
_________________ Never give up
WM : E16 the true enlightenment
achim |
|
Back to top |
|
|
3PO Veteran
Joined: 26 Nov 2006 Posts: 1110 Location: Schwabenländle
|
Posted: Sun Feb 01, 2009 4:43 pm Post subject: |
|
|
zcat brauche ich nicht, da meine Dateien nicht komprimiert sind.
grep hilft mit leider auch nicht unbedingt weiter, da ich in jeder Zeile etwas anderes stehen habe, z.B:
abc.foo
Code: | asdfasdf
123ggg
/etc/foo
yyyyy |
|
|
Back to top |
|
|
franzf Advocate
Joined: 29 Mar 2005 Posts: 4565
|
Posted: Sun Feb 01, 2009 5:03 pm Post subject: |
|
|
Ich bin kein Bash-Guru, drum ist das vllt. bissl grob.
Code: | for line in $(cat abc.foo); do if [ "$(grep $line xyz.foo)" == "" ]; then echo $line >> xyz.foo; fi; done |
(ungetestet, einfach hier ins Fenster getippt)
Aber es wird wohl nicht anders gehen, als die eine Datei Zeile für Zeile durch zu gehen und prüfen, ob sie schon in der anderen Datei existiert. |
|
Back to top |
|
|
3PO Veteran
Joined: 26 Nov 2006 Posts: 1110 Location: Schwabenländle
|
Posted: Sun Feb 01, 2009 5:18 pm Post subject: |
|
|
1000 thx @ franzf,
genau danach hatte ich gesucht, allerdings muss man beim Testbefehl immer ein Leerzeichen vor und hiner dem "[" und dem "]" vorhanden ist. |
|
Back to top |
|
|
Earthwings Bodhisattva
Joined: 14 Apr 2003 Posts: 7753 Location: Germany
|
Posted: Sun Feb 01, 2009 9:56 pm Post subject: |
|
|
Falls die Dateien groß sind, wird das auf die Weise ziemlich lange dauern. Etwas schneller (durch grep -q) ist Code: | while read line
do
grep -q "$line" xyz.foo || echo "$line" >> xyz.foo
done < abc.foo |
Wenn es auf die Reihenfolge der Zeilen nicht ankommt, mach es mittels Code: | sort abc.foo xyz.foo | uniq | Ist kürzer und bei großen Dateien deutlich schneller. _________________ KDE |
|
Back to top |
|
|
3PO Veteran
Joined: 26 Nov 2006 Posts: 1110 Location: Schwabenländle
|
Posted: Sun Feb 01, 2009 10:17 pm Post subject: |
|
|
thx @ Earthwings,
auch das werde ich mal testen.
Btw: Bei den File handelt es sich um configs für eine Installationsroutine, die ich eben via Script an die gegebene Hardware anpassen will.
D.h es handelt sich um files mit max 20 Zeilen. Dabei ist mir eben wichtig, dass wenn das Installsript ein weiters Mal aufgerufen wird, die Einträge dann nicht doppelt eingetragen werden. |
|
Back to top |
|
|
3PO Veteran
Joined: 26 Nov 2006 Posts: 1110 Location: Schwabenländle
|
Posted: Mon Feb 02, 2009 2:04 pm Post subject: |
|
|
Ich habe gerade nochmal dieses getestet:
Code: | for line in $(cat abc.foo); do if [ "$(grep $line xyz.foo)" == "" ] ; then echo $line >> xyz.foo; fi; done |
Dabei ist mir aufgefallen, dass Leerzeichen als Zeilenumbrüche interpretiert werden.
Gibt es dafür auch eine Lösung?
Beispiel:
aus:
Code: | /dev /var/test/chroot0/dev none bind
/lib /var/test/chroot0/lib none bind
/bin /var/test/chroot0/bin none bind
/usr /var/test/chroot0/usr none bind |
wird:
Code: | /dev /var/test/chroot0/dev
/lib /var/test/chroot0/lib
/bin /var/test/chroot0/bin
/usr /var/test/chroot0/usr |
Last edited by 3PO on Mon Feb 02, 2009 2:11 pm; edited 1 time in total |
|
Back to top |
|
|
69719 l33t
Joined: 20 Sep 2004 Posts: 865
|
Posted: Mon Feb 02, 2009 2:09 pm Post subject: |
|
|
3PO wrote: | Ich habe gerade nochmal dieses getestet:
Code: | for line in $(cat abc.foo); do if [ "$(grep $line xyz.foo)" == "" ] ; then echo $line >> xyz.foo; fi; done |
Dabei ist mir aufgefallen, dass Leerzeichen als Zeilenumbrüche interpretiert werden.
Gibt es dafür auch eine Lösung? |
Code: |
cat abc.foo | while read line; do [ -z "$(grep "$line" xyz.foo)" ] && echo "$line" >> xyz.foo; done
|
|
|
Back to top |
|
|
3PO Veteran
Joined: 26 Nov 2006 Posts: 1110 Location: Schwabenländle
|
Posted: Mon Feb 02, 2009 2:42 pm Post subject: |
|
|
@ escor,
das geht leider auch nicht.
Damit kommen Fehlermeldungen wie diese:
Quote: | .....
grep: none: Datei oder Verzeichnis nicht gefunden
grep: bind: Datei oder Verzeichnis nicht gefunden
grep: none: Datei oder Verzeichnis nicht gefunden
grep: bind: Datei oder Verzeichnis nicht gefunden
grep: none: Datei oder Verzeichnis nicht gefunden
grep: bind: Datei oder Verzeichnis nicht gefunden
grep: none: Datei oder Verzeichnis nicht gefunden
grep: bind: Datei oder Verzeichnis nicht gefunden
grep: none: Datei oder Verzeichnis nicht gefunden
...... |
|
|
Back to top |
|
|
3PO Veteran
Joined: 26 Nov 2006 Posts: 1110 Location: Schwabenländle
|
Posted: Mon Feb 02, 2009 3:23 pm Post subject: |
|
|
[ERLEDIGT]
ich habe nun den Vorschlag von Earthwings genommen, damit funktionert es 100%ig
Code: | while read line
do
grep -q "$line" xyz.foo || echo "$line" >> xyz.foo
done < abc.foo |
Allerdings kommt wenn xyz.foo nicht existeiert eine Fehlermeldung: "Datei oder Verzeichnis nicht gefunden", kopiert wir aber trotzdem.
ich habe mal um den Fehler zu unterdrücken ein "touch" mit eingebaut.
Code: | touch xyz.foo
while read line
do
grep -q "$line" xyz.foo || echo "$line" >> xyz.foo
done < abc.foo |
1000 thx nochmal an alle Helfer. |
|
Back to top |
|
|
|