Ausdrücke in Textdatei suchen und löschen

PlatonTux

PlatonTux

Jungspund
[gelöst] Ausdrücke in Textdatei suchen und löschen

Hallo alle zusammen,

als erstes möchte ich mir kurz vorstellen.

Ich bin 20 Jahre alt und arbeite im Messtechnik Labor eines technischen Unternemens für Autoteile. Privat verwende ich nur Linux Distributionen und bin seit einigen Wochen einfrig an Shell-Skripte Basteln.

Ich habe mich hier zwar gerade registriert aber verfolge seit einigen Wochen hier die Rubriken Linux und Shell sehr interessiert mit.



Zu meinem Problem (was für euch bestimmt keine große Angelegenheit ist :)) ):
Mit dem Befehl "rpm -qa --queryformat '%{NAME} \n' > meine_pakete.text" werden alle bei mir im System installierten Pakete in einer Textdatei mit dem Namen "meine_pakete.text" gespeichert. Alle Pakete werden dabei in eine sehr lange Zeile (mit Leerzeichen voneinander getrennt) geschrieben. So weit so gut.
Nun möchte ich aus dieser Zeile nach bestimmten Paketen suchen und wenn möglich diese dann entfernen.

Ich weiß, dass ich es auch mit der Paketeverwaltung "apt" bzw. Synaptic viel bequemer erledigen könnte. Aber ich möchte es auch mit Hilfe der Shell mal selber experimentieren ... :D

Hat darum jemand eine Idee, wie ich also in der ersten Zeile einer Textdatei nach einem bestimmten Ausdruck (z.B. "firefox") suchen und wenn es vorhanden ist dann diesen Ausdruck aus dieser Zeile löschen kann bzw. mit einem anderen Ausdruck ersetzen ?

Ich bedanke mich schon im Voraus für eure Antworten :)


Mit freundlichen Grüßen: PlatonTux
 
Zuletzt bearbeitet:
Ich denke das Stichwort heisst 'sed'
Code:
sed -i 's/suchwort/ersetze/' infile.txt
aber schau dir vorher unbeding noch 'man sed' an...

Gruss
d22
 
Hallo nochmals,

habe vergessen mitzuteilen, welches Betriebssystem ich momentan verwenden:
Also ich benutze derzeit SAM Linux (- ist ein abkömmling von PCLinuxOS)
Die Schell ist eine "übliche" Linux-Bash.

MfG: PlatonTux
.
.
.
EDIT (autom. Beitragszusammenführung) :
.

Ich denke das Stichwort heisst 'sed'
Code:
sed -i 's/suchwort/ersetze/' infile.txt
aber schau dir vorher unbeding noch 'man sed' an...

Gruss
d22



Bua das ^^^ ging ja schnell mit dem Antworten. :)

Wenn ich fragen darf, wo zu steht das kleien s vor dem /suchwort/ersetze/ ?


MfG: PlatonTux
 
Zuletzt bearbeitet:
Wenn du nur in der ersten Zeile suchen willst und dort alle Vorkommen löschen:
Code:
sed  -i -e '1s/firefox/neuer Text/g' input
-i kennt aber nur GNU sed!

s/search/replace/(option)

s ist der Befehl für Ersetzen.
Gruß Wolfgang
 
Leute ihr alle seit echt klasse :) :)

Danke noch mals - hat tadellos geklappt.

Aber eine Frage hätte ich noch zu:
-i kennt aber nur GNU sed!

Heißt das, dass ich mein Skript mit dieser Funktion nur unter Linux verwenden kann oder funktioniert es unter BSD und Unix auch?


MfG: PlatonTux
 
Zuletzt bearbeitet:
Heißt das, dass ich mein Skript mit dieser Funktion nur unter Linux verwenden kann oder funktioniert es unter BSD und Unix auch?


MfG: PlatonTux

Das kommt einfach darauf an, welche sed Version installiert ist.
Solaris beispielsweise verwendet ein eigenes sed, was das nicht kennt.
Du musst dort mit temporären Dateien arbeiten und dann kopieren.

Code:
sed -e 's/foo/bar/g' input >output && cat output >input && rm output
 
Hallo Wolfang,

danke für die freundliche erklärung, nun hab' ich es auch verstanden:D

Mit hilfe von Google findet man zahlreiche Erklärungen und Beispiele zu "sed". Hier eine Seite, die ich persönlich für andere Anfänger wie mir gerne weiterempfehle:
http://de.gentoo-wiki.com/Sed


Somit wäre meine Frage beantwortet - werde gleich ein "[gelöst]" vor dem Titel schreiben :)


Wünsche euch allen noch einen schönen Tag.
Mit freundlichen Grüßen
PlatonTux
.
.
.
EDIT (autom. Beitragszusammenführung) :
.

Guten Abend,

wie schon bei meinem ersten Beitrag erwähnt, schreibt der Befehl
Code:
rpm -qa --queryformat " "%{NAME} > meine_pakete.text
alle installierten Pakte nacheinander in eine Zeile und speichert sie in die Textdatei "meine_pakete.text". Alle Paketenamen in dieser Textdatei werden dann in einer langen Zeile mit einem Leerzeichen voneinander getrennt geschrieben.

Nun versuche ich krampfhaft Pakete mit "kde" im Namen aus dieser langen Zeile zu löschen und dann diese sozusagen "gefiltere" Liste wieder in eine Textdatei "meine_pakete_gefiltert.text" zu speichern.

Jedoch komme ich mit dem Syntax von sed einfach nicht zurecht. :(

Kann mir bitte jemand helfen?

Hier ist mein bisheriger "Werk":
Code:
#! /bin/bash

rpm -qa --queryformat " "%{NAME} > meine_pakete.text

$(sed -e 's/kde.* //g' ) > meine_pakete_gefiltert.text


exit 0

Wenn ich dieses Skript ausführe kommt gar nichts, es "steht" irgenwie, bis ich mit STRG+C abbreche.



Mit freundlichen Grüßen: PlatonTux
 
Zuletzt bearbeitet:
Wolfgang schrieb:
Code:
sed -e 's/foo/bar/g' input >output && cat output >input && rm output
OMG UUOC!!1
warum nicht einfach
Code:
sed -e 's/foo/bar/g' input >output && mv output input
:?
ANYWHO, @threadersteller:

hast du was dagegen die lange zeile in viele kurze zeilen zu verwandeln? weil dann könntest du mit grep ans "filtern" gehen, was wesentlich einfacher ist als jedes mal mit sed rumzufrickeln:
Code:
perl -pe 's/[[:space:]]+/\n/g' paket.liste > paket.liste_ein_paket_pro_zeile
das lässt sich dann besser verarbeiten, da die meisten dieser kleinen texttools zeilenbasiert arbeiten. wenn du aus dieser datei dann die pakete mit "kde" im namen herausfiltern willst kannst du einfach die "-v" option von grep verwenden:
Code:
grep -vi 'kde' paket.liste_ein_paket_pro_zeile > neue_liste
die "v" option gibt nur die zeilen aus, in denen das angegebene muster nicht gefunden wurde. (v steht wahrscheinlich für vorbid BWAHAHA). "i" steht für "case insensitive", also würden auch zeilen mit bsp. "kDE" oder "KdE" oder "kdE" etc. herausgefiltert werden.

edit: erm und zu dieser zeile hier:
Code:
$(sed -e 's/kde.* //g' ) > meine_pakete_gefiltert.text
:|
aalso erstmal hat dein sed keine input datei die es verarbeiten kann, deshalb liest es den text dann von stdin, also deiner tastatur. zweitens müsstest du zumindest ein "echo" vor diese $(...) konstruktion setzen, sonst würde die bash versuchen den output des kommandos "sed -e 's/kde.*//g'" als befehl anzusehen...
Code:
sed -e 's/kde.* //g'  meine_pakete.text > meine_pakete_gefiltert.text
so müsste es gehen (ungetestet)
 
Zuletzt bearbeitet:
Hallo
Ich frage mich allerdings, warum das das dann erst im Querformat ausgibst?

Geht aber auch recht einfach mit sed.
Code:
sed -e 's/\(kde[^[:space:]]\)//ig' input

Übrigens kommt bei dir nix, weil sed eine Eingabe erwartet.

warum nicht einfach...
Erwischt.
Darfst mich hinrichten.

Einmal darf ich das auch.

Aber das hier:
Code:
perl -pe 's/[[:space:]]+/\n/g' paket.liste > paket.liste_ein_paket_pro_zeile
grep....
ist auch zuviel.
perl kennt Wortgrenzen \b
;)


Gruß Wolfgang
 
Bua mit deiner Anleitung funktionierts - danke :))

Also dieses Forum ist für mich eine wahre Fundgrube - danke euch allen, ihr seit echte Gurus :)



Code:
$(sed -e 's/kde.* //g' ) > meine_pakete_gefiltert.text
:|
aalso erstmal hat dein sed keine input datei die es verarbeiten kann, deshalb ließt es den text dann von stdin, also deiner tastatur. zweitens müsstest du zumindest ein "echo" vor diese $(...) konstruktion setzen, sonst würde die bash versuchen den output des kommandos "sed -e 's/kde.*//g'" als befehl anzusehen...
Code:
sed -e 's/kde.* //g'  meine_pakete.text > meine_pakete_gefiltert.text
so müsste es gehen (ungetestet)

Also diese Variante funktioniert dank deiner Korrektur - jedoch werden hier die Pakete zwischen den kde Paketen auch entfernt.
 
jedoch werden hier die Pakete zwischen den kde Paketen auch entfernt.
naja, erstmal: der quantifier "*" ist greedy per default, dh er match so viele zeichen wie möglich. in sed kann man den afaik nicht auf "nicht-greedy" setzen. (in perl geht das zb)
deine regex matcht also alles was mit "kde" startet und mit einem leerzeichen aufhört, und zwar matcht die längste möglichkeit. genau wegen dieser probleme hab ich dir dazu geraten deine liste in eine "ein paket pro zeile" zu transformieren...

edit: wobei das
Code:
rpm -qa --queryformat '%{NAME} \n'
doch eigentlich sowieso (vom anschein her, ich kenne rpm nicht) ein paket pro zeile ausgeben sollte, oder?
?_?
 
Zuletzt bearbeitet:
edit: wobei das
Code:
rpm -qa --queryformat '%{NAME} \n'
doch eigentlich sowieso (vom anschein her, ich kenne rpm nicht) ein paket pro zeile ausgeben sollte, oder?
?_?

Ich denke das ist bestimmt auch möglich aber ich bin vorerst froh, das ich es überhaupt so weit gebracht habe mit eurer Unterstützung (mit der Matrie bin ich noch nicht so gut vertraut :headup: )
Es liegt, ich vermute, an den Parametern für rpm.
 
Ach die Perlvariante All in One ohne Ersetzen - schneller:
Code:
perl -ane 'print join " ",grep{!/kde/}@F' input
 

Ähnliche Themen

3 letzte Zeile löschen oder ab Zeile 55 Muster suchen und löschen

Zeilenweise suchen, löschen und ersetzen / Inhalt einfügen

Zeilen löschen und ersetzen mit sed

Unix-Kernel + Unix-Shells: Ein paar Grundfragen

Suche Mitstreiter

Zurück
Oben