Bash-Script > Wort finden und komplette Zeile löschen.

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
fte213
Beiträge: 70
Registriert: 11.01.2004 12:31:28
Wohnort: 74889 Sinsheim

Bash-Script > Wort finden und komplette Zeile löschen.

Beitrag von fte213 » 24.05.2004 17:38:00

Hallo!

Hab zwar schon rumgeschaut und bin mit meinem Script auch schnell weiter gekommen, aber mir fehlt noch ein Detail.

Und zwar kann es vorkommen, dass in einer Datei was doppelt eingetragen wird und um das zu verhindern möchte vorher immer alles löschen und es dann bei ausführen des Scripts neu eintragen.

Also nicht alles in der Datei sonder halt nur diese Zeilen wo entweder doppelt sind oder wo ich weiss dass diese doppelt eingetragen sein könnten und auch weiss was dann in der Zeile steht und dies somit suchen könnte.

Das heisst aber, dass ich es erstmal was suchen muss, was in der Zeile steht und dann die Komplette Zeile löschen muss!

Gibts da ein Beispielscript oder hat jemand eine Idee für die Syntax.

Wusste jetzt auch nicht wie ich es besser erklären kann, ich hoffe es kann jemand was damit anfangen.

Danke!

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Beitrag von peschmae » 24.05.2004 19:00:20

mit Sed z.B.?

sed s/.*such.*// -i datei.txt
oder
sed s/.*such.*// <datei.txt
wobei ersteres die Datei verändert und das zweite die geänderte Datei ausgibt (aber die Änderungen nicht in die Datei schreibt)

MfG Peschmä

roli
Beiträge: 3174
Registriert: 10.09.2003 17:39:58

Beitrag von roli » 24.05.2004 21:45:53

Hi,

sed ist eine prima Loesung, wenn es allerdings nicht auf die Reihenfolge der Zeilen in der "aussortierten" Datei ankommt, koenntest du auch

Code: Alles auswählen

sort -u <EINGABEDATEI >AUSGABEDATEI
verwenden.
Roland


"Aber wenn du schon so unwissend bist, davon noch nicht gehört zu haben,
so will ich es doch als gut ansehen, daß du lieber einmal töricht fragst,
als weiterhin nichts von etwas zu wissen, das man doch wissen sollte."
aus "Die Edda des Snorri Sturluson", "Gylfis Täuschung"

roli
Beiträge: 3174
Registriert: 10.09.2003 17:39:58

Beitrag von roli » 24.05.2004 21:46:17

Hi,

sed ist eine prima Loesung, wenn es allerdings nicht auf die Reihenfolge der Zeilen in der "aussortierten" Datei ankommt, koenntest du auch

Code: Alles auswählen

sort -u <EINGABEDATEI >AUSGABEDATEI
verwenden.
Roland


"Aber wenn du schon so unwissend bist, davon noch nicht gehört zu haben,
so will ich es doch als gut ansehen, daß du lieber einmal töricht fragst,
als weiterhin nichts von etwas zu wissen, das man doch wissen sollte."
aus "Die Edda des Snorri Sturluson", "Gylfis Täuschung"

Benutzeravatar
pdreker
Beiträge: 8298
Registriert: 29.07.2002 21:53:30
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Nürnberg

Beitrag von pdreker » 25.05.2004 00:10:26

Du willst also alle Zeilen einer Datei haben, die einen bestimmten String *nicht* enthalten? Nichts leichter als das:

Code: Alles auswählen

grep -v STRING Datei.txt
Patrick
Definitely not a bot...
Jabber: pdreker@debianforum.de

fte213
Beiträge: 70
Registriert: 11.01.2004 12:31:28
Wohnort: 74889 Sinsheim

Beitrag von fte213 » 25.05.2004 00:21:57

sed s/.*such.*// -i datei.txt
das will irgendwie net, obwohl ich genau das deine erklärung nach wollte!

die option "s" ist ja schon unbekannt.


wo genau haste das denn gesehen? bzw. vielleicht komm ich grad ein wenig mit der syntax und den /.* durcheinander!

fte213
Beiträge: 70
Registriert: 11.01.2004 12:31:28
Wohnort: 74889 Sinsheim

Beitrag von fte213 » 25.05.2004 02:40:47

hab nochmal nachgeschaut und das ganze jetzt folgendermassen gelöst:

Code: Alles auswählen

sed -e '/T1/d' /etc/iproute2/rt_tables > /etc/iproute2/rt_tables.temp

sed -e '/T2/d' /etc/iproute2/rt_tables.temp > /etc/iproute2/rt_tables.temp2

cp /etc/iproute2/rt_tables.temp2 /etc/iproute2/rt_tables

soweit ich es überblicken und ausprobieren konnte, macht es genau das was ich wollte.

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Beitrag von peschmae » 25.05.2004 07:50:20

naja, das -i <dateiname> geht nicht bei allen sed - aber bei denen von Debian schon (die GNU-Dinger halt)

MfG Peschmä

fte213
Beiträge: 70
Registriert: 11.01.2004 12:31:28
Wohnort: 74889 Sinsheim

Beitrag von fte213 » 25.05.2004 10:10:40

Hm, hatte es probiert, aber irgendwie werd ich da wohl einen kleinen Syntax fehler eingebaut haben.

Konnt auch nichts finden soweit.

Also wenn Du anhand des Beispiels von mir nochmal eine Zeile bauen kannst probier ich das nochmal aus, dann kann ich mir die .temp-Dateien sparen :-)

Danke.

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Beitrag von peschmae » 25.05.2004 11:40:34

einfach statt
datei > datei.tmp
ein
-i datei
machen. Das wäre also so:

Code: Alles auswählen

sed -e '/T1/d' -i /etc/iproute2/rt_tables 
sed -e '/T2/d' -i /etc/iproute2/rt_tables
noch netter wäre allerdings

Code: Alles auswählen

 sed -e '/T[12]/d' -i /etc/iproute2/rt_tables
das [12] matcht 1 oder 2 :)

MfG Peschmä

roli
Beiträge: 3174
Registriert: 10.09.2003 17:39:58

Beitrag von roli » 27.05.2004 21:43:50

Hi,

joh, da ist'n Syntax Fehler:
peschmae hat geschrieben:sed s/.*such.*// <datei.txt
Um den Ausdruck herum fehlen Hochkommas, also
sed 's/.*such.*//' <datei.txt
Roland


"Aber wenn du schon so unwissend bist, davon noch nicht gehört zu haben,
so will ich es doch als gut ansehen, daß du lieber einmal töricht fragst,
als weiterhin nichts von etwas zu wissen, das man doch wissen sollte."
aus "Die Edda des Snorri Sturluson", "Gylfis Täuschung"

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Beitrag von peschmae » 28.05.2004 09:38:27

die sind aber nicht nötig :wink:

Code: Alles auswählen

peschmae@satellite:~$ sed s/.*such.*// <datei.txt | md5sum
6515c621dac69beff442141ebbd2c2fa  -
peschmae@satellite:~$ sed 's/.*such.*//' <datei.txt | md5sum
6515c621dac69beff442141ebbd2c2fa  -
Ach ja, und datei.txt sieht so aus:

Code: Alles auswählen

peschmae@satellite:~$ cat datei.txt 
öalsdjflasd
falösdfjölakjsdf
asklöfjlasdsuch
asdöfljasldf
asdökfjsuchasödf
MfG Peschmä

roli
Beiträge: 3174
Registriert: 10.09.2003 17:39:58

Beitrag von roli » 28.05.2004 10:25:23

Hi,

wird der * denn dann nicht von der Shell expandiert? Noetig sind sie auf jeden Fall, wenn du z.B. nach dem Zeilenende, also $ such'st, daher habe ich es mir angewoehnt die Hochkomma einfach immer zu verwenden, dann muss ich mir nicht ueberlegen wann ich sie brauche und wann nicht.
Roland


"Aber wenn du schon so unwissend bist, davon noch nicht gehört zu haben,
so will ich es doch als gut ansehen, daß du lieber einmal töricht fragst,
als weiterhin nichts von etwas zu wissen, das man doch wissen sollte."
aus "Die Edda des Snorri Sturluson", "Gylfis Täuschung"

Benutzeravatar
Joghurt
Beiträge: 5244
Registriert: 30.01.2003 15:27:31
Wohnort: Hamburg
Kontaktdaten:

Beitrag von Joghurt » 28.05.2004 12:44:46

roli hat geschrieben:wird der * denn dann nicht von der Shell expandiert?
Nicht, wenn
  • Es keine Datei gibt, auf die das Muster passt
  • es in einfachen Anführungszeichen steht: solche Strings werden allgemein von der Shell in Ruhe gelassen.
Aus letzterem Grunde schreibt man ja auch immer

Code: Alles auswählen

sed -e '...'
statt

Code: Alles auswählen

sed -e "..."

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Beitrag von peschmae » 29.05.2004 08:10:54

das * wird weder in ' ' noch in " " expandiert.

Der Unterschied zwischen den beiden ist das zwischen ' ' keine Variablen expandiert werden - zwischen " " hingegen schon

'$HOME' liefert also $HOME (wortwörtlich) während "$HOME" wie auch $HOME den Inhalt - also /home/peschmae liefern

Peschmä

Benutzeravatar
Joghurt
Beiträge: 5244
Registriert: 30.01.2003 15:27:31
Wohnort: Hamburg
Kontaktdaten:

Beitrag von Joghurt » 29.05.2004 15:55:16

peschmae hat geschrieben:das * wird weder in ' ' noch in " " expandiert.
Trööt! Ja, du hast recht! Ich selbst schreibe ja auch oft "blabla*"...

Muss mit den Gedanken woanders gewesen sein, als ich das postete...

Benutzeravatar
Joghurt
Beiträge: 5244
Registriert: 30.01.2003 15:27:31
Wohnort: Hamburg
Kontaktdaten:

Beitrag von Joghurt » 29.05.2004 15:55:32

peschmae hat geschrieben:das * wird weder in ' ' noch in " " expandiert.
Trööt! Ja, du hast recht! Ich selbst schreibe ja auch oft "blabla*"... :?

Muss mit den Gedanken woanders gewesen sein, als ich das postete...

Olaf Dietsche
Beiträge: 520
Registriert: 12.06.2003 23:18:50
Wohnort: Siegburg

Beitrag von Olaf Dietsche » 29.05.2004 16:26:19

fte213 hat geschrieben:hab nochmal nachgeschaut und das ganze jetzt folgendermassen gelöst:

Code: Alles auswählen

sed -e '/T1/d' /etc/iproute2/rt_tables > /etc/iproute2/rt_tables.temp

sed -e '/T2/d' /etc/iproute2/rt_tables.temp > /etc/iproute2/rt_tables.temp2

cp /etc/iproute2/rt_tables.temp2 /etc/iproute2/rt_tables
Du kannst bei sed auch mehrere Ausdrücke angeben. Damit sparst du dir die Zwischenschritte:

Code: Alles auswählen

sed -e '/T1/d' -e '/T2/d' /etc/iproute2/rt_tables > /etc/iproute2/rt_tables.temp
Gleiches gilt für grep:

Code: Alles auswählen

grep -v -e T1 -e T2 /etc/iproute2/rt_tables > /etc/iproute2/rt_tables.temp

Benutzeravatar
pdreker
Beiträge: 8298
Registriert: 29.07.2002 21:53:30
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Nürnberg

Beitrag von pdreker » 29.05.2004 18:12:16

Ich habe es zwar ca. 10 Posts weiter oben schon geschrieben, aber was ist mit "grep -v wort datei" nicht in Ordnung? "grep -v" macht genau das umgekehrte von grep: es gibt alle Zeilen aus, die den String "wort" nicht enthalten...

Patrick
Definitely not a bot...
Jabber: pdreker@debianforum.de

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Beitrag von peschmae » 29.05.2004 21:12:31

Gar nix ist nicht in Ordnung. ;)

Aber wenn einer anfängt meine funktionierende Lösung schlechtzumachen und unüberprüfte Behauptungen zuv erbreiten werde ich ihn doch wohl korrigieren dürfen :wink:

Ich schäm mich übrigens immer noch dafür, dass ich immer gleich zu sed greife und Grep so sträflich vernachlässige :oops:

MfG Peschmä

roli
Beiträge: 3174
Registriert: 10.09.2003 17:39:58

Beitrag von roli » 31.05.2004 11:14:09

Hi,

das war ja auch der Grund warum ich in meinem ersten Posting auf die "fehlenden" Hochkommata hingewiesen habe. Ich verwende sie halt immer, bis jetzt gabe es noch keinen Grund sie nicht zu verwenden.
Roland


"Aber wenn du schon so unwissend bist, davon noch nicht gehört zu haben,
so will ich es doch als gut ansehen, daß du lieber einmal töricht fragst,
als weiterhin nichts von etwas zu wissen, das man doch wissen sollte."
aus "Die Edda des Snorri Sturluson", "Gylfis Täuschung"

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Beitrag von peschmae » 31.05.2004 21:27:58

*ggg*

Naja, vielleicht wegen eventueller Variablen die du dort drin verwenden möchtest?
Naja, ich verwende Sie nur wenns was bringt :)

MfG Peschmä

Benutzeravatar
foresthus
Beiträge: 1
Registriert: 02.01.2006 16:44:17

Fast perfekt, aber ...

Beitrag von foresthus » 02.01.2006 16:52:42

pdreker hat geschrieben:Ich habe es zwar ca. 10 Posts weiter oben schon geschrieben, aber was ist mit "grep -v wort datei" nicht in Ordnung? "grep -v" macht genau das umgekehrte von grep: es gibt alle Zeilen aus, die den String "wort" nicht enthalten...

Patrick
Mit grep funktioniert es prima!

Allerdings reicht ein

Code: Alles auswählen

grep -v
nicht aus! Falls sich in der Datei ähnliche Worte befinden, werden nämlich dann alle Zeilen nicht angezeigt.

Möchte man nun nur die Zeile nicht dargestellt bekommen, die 100% 'wort' enthält und nicht 'wort20', so sollte man folgenden Befehl nutzen:

Code: Alles auswählen

grep -v wort -w /tmp/datei.txt
Mit dieser abgeänderten Variante erhält man eine Ausgabe ohne die Zeile mit dem Inhalt 'wort'!

:D

Antworten