Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Reihenfolge der Ergebnisse von grep aendern

6 views
Skip to first unread message
Message has been deleted

Manuel Reimer

unread,
Nov 18, 2009, 3:46:48 AM11/18/09
to
Wolfgang Klein wrote:
> Auf diese Ausgabe will ich grep loslassen, das nach bestimmten W�rtern
> suchen soll. So weit, so unspektakul�r.

> Aber: kann ich grep auch sagen, es m�ge die Ergebnisse der Suche in
> anderer Reihenfolge pr�sentieren, als sie gefunden wurden?

Nein. Grep arbeitet immer von oben nach unten und nur Zeilenweise.

> Im obigen Bsp sollte also der Befehl

> programm | grep -E "Zeile3|Zeile1|Zeile2"

> als Ergebnis liefern:

> Dies ist Zeile3
> Dies ist Zeile1
> Dies ist Zeile2

ausgabe=$(programm)
z1=$(echo "$ausgabe" | grep Zeile1)
z2=$(echo "$ausgabe" | grep Zeile2)
z3=$(echo "$ausgabe" | grep Zeile3)
echo $'$z3\n$z1\n$z2'

CU

Manuel

--
Alle wollen zur�ck zur Natur - aber keiner zu Fu�
Der Mensch erfand Maschinen, um sich damit die Arbeit zu erleichtern.
Nur leider hat er vergessen, rechtzeitig damit aufzuh�ren...
Beitr�ge mit *X-No-Html Header* kann ich weder lesen, noch beantworten!

Manuel Reimer

unread,
Nov 18, 2009, 5:03:56 AM11/18/09
to
Manuel Reimer wrote:
> ausgabe=$(programm)
> z1=$(echo "$ausgabe" | grep Zeile1)
> z2=$(echo "$ausgabe" | grep Zeile2)
> z3=$(echo "$ausgabe" | grep Zeile3)
> echo $'$z3\n$z1\n$z2'

Nachtrag: Die letzte Zeile ist so falsch. Versuche es so:

ausgabe=$(programm)
z1=$(echo "$ausgabe" | grep Zeile1)
z2=$(echo "$ausgabe" | grep Zeile2)
z3=$(echo "$ausgabe" | grep Zeile3)

echo "$z3"
echo "$z1"
echo "$z2"

Jochen Schulz

unread,
Nov 18, 2009, 5:56:53 AM11/18/09
to
* Wolfgang Klein:
>
> Aber: kann ich grep auch sagen, es möge die Ergebnisse der Suche in
> anderer Reihenfolge präsentieren, als sie gefunden wurden?

Nein. Grep geht den Input einfach zeilenweise durch und entscheidet für
jede Zeile, ob sie ausgegeben werden soll, oder nicht. Das ist alles.

> Im obigen Bsp sollte also der Befehl
>
> programm | grep -E "Zeile3|Zeile1|Zeile2"
>
> als Ergebnis liefern:
>
> Dies ist Zeile3
> Dies ist Zeile1
> Dies ist Zeile2

Um das programmatisch abbilden zu können, müsstest Du das
Sortierkriterium konkret benennen. Das Beispiel sieht eher "unsortiert"
aus.

Soll die Reihenfolge der Ausgabe wie im Beispiel von der Reihenfolge der
Alternativen in Deinem regulären Ausdruck abhängen, würde ich wie schon
vorgeschlagen drei grep-Aufrufe machen. Ist nicht sonderlich effizient,
aber lesbar. Wenn das zu langsam ist, würde ich wie oben erst alle
Ergebnisse holen und nur noch die dann einzeln per grep sortieren:

$ programm | grep -E "a|b|c" > tmp.0
$ grep "a" tmp.0 > tmp.a
$ grep "b" tmp.0 > tmp.b
$ grep "c" tmp.0 > tmp.c
$ cat tmp.a tmp.b tmp.c > result

Die letzten vier Schritte kann man zumindest in der bash auch ohne
temporäre Dateien lösen:

$ cat <(grep "a" tmp.0) <(grep "b" tmp.0) <(grep "c" tmp.0) > result

Um das portabel zu machen, müsste man wohl selbst mit named pipes
arbeiten.

J.
--
I want to look younger than my friends so I will fight ageing as long as
I can.
[Agree] [Disagree]
<http://www.slowlydownward.com/NODATA/data_enter2.html>

Jochen Schulz

unread,
Nov 18, 2009, 6:33:29 AM11/18/09
to
* Ingrid:

>
> $ programm | grep -E "a|b|c" > tmp.0
> $ grep "a" tmp.0 > tmp.a
> $ grep "b" tmp.0 > tmp.b
> $ grep "c" tmp.0 > tmp.c
> $ cat tmp.a tmp.b tmp.c > result

Statt tmp.a bis tmp.c kann man natürlich auch einfach alles per '>>'
direkt ins 'result' schreiben…

J.
--
I am not scared of death but terrified of people in Tommy Hilfiger
sweatshirts.
[Agree] [Disagree]
<http://www.slowlydownward.com/NODATA/data_enter2.html>

Florian Diesch

unread,
Nov 18, 2009, 7:13:40 AM11/18/09
to
Jochen Schulz <usenet...@well-adjusted.de> writes:

> * Wolfgang Klein:
>>
>> Aber: kann ich grep auch sagen, es m�ge die Ergebnisse der Suche in
>> anderer Reihenfolge pr�sentieren, als sie gefunden wurden?
>
> Nein. Grep geht den Input einfach zeilenweise durch und entscheidet f�r


> jede Zeile, ob sie ausgegeben werden soll, oder nicht. Das ist alles.
>
>> Im obigen Bsp sollte also der Befehl
>>
>> programm | grep -E "Zeile3|Zeile1|Zeile2"
>>
>> als Ergebnis liefern:
>>
>> Dies ist Zeile3
>> Dies ist Zeile1
>> Dies ist Zeile2
>

> Um das programmatisch abbilden zu k�nnen, m�sstest Du das


> Sortierkriterium konkret benennen. Das Beispiel sieht eher "unsortiert"
> aus.
>
> Soll die Reihenfolge der Ausgabe wie im Beispiel von der Reihenfolge der

> Alternativen in Deinem regul�ren Ausdruck abh�ngen, w�rde ich wie schon


> vorgeschlagen drei grep-Aufrufe machen. Ist nicht sonderlich effizient,

> aber lesbar. Wenn das zu langsam ist, w�rde ich wie oben erst alle


> Ergebnisse holen und nur noch die dann einzeln per grep sortieren:
>
> $ programm | grep -E "a|b|c" > tmp.0
> $ grep "a" tmp.0 > tmp.a
> $ grep "b" tmp.0 > tmp.b
> $ grep "c" tmp.0 > tmp.c
> $ cat tmp.a tmp.b tmp.c > result

Dabei werden Zeilen, in denen mehrere Alternativen gefunden werden, auch
mehrfach aufgef�hrt. Das Ergebnis entspricht dann also nicht einer
Umsortierung der Original-Suche.


> Die letzten vier Schritte kann man zumindest in der bash auch ohne

> tempor�re Dateien l�sen:


>
> $ cat <(grep "a" tmp.0) <(grep "b" tmp.0) <(grep "c" tmp.0) > result
>

> Um das portabel zu machen, m�sste man wohl selbst mit named pipes
> arbeiten.

(grep "a" tmp.0; grep "b" tmp.0; grep "c" tmp.0) > result


Florian
--
<http://www.florian-diesch.de/software/pdfrecycle/>

Message has been deleted

Tobias Nissen

unread,
Nov 18, 2009, 11:46:28 AM11/18/09
to
Wolfgang Klein wrote:
> Am 18.11.2009 09:19 schrieb ich:
>> ...

>> Aber: kann ich grep auch sagen, es möge die Ergebnisse der Suche in
>> anderer Reihenfolge präsentieren, als sie gefunden wurden?
>> ...
>
> Danke für alle Antworten.
>
> Den Trick mit einer temporären Zwischendatei hatte ich schon
> verwirklicht. Ich hatte nur noch gehofft, ohne diese Krücke
> auszukommen, um die Verarbeitung zu beschleunigen.

Du wirst ja sicher Perl installiert haben, wäre das eine Alternative?

Dann kannst Du das Ding hier abspeichern

#!/usr/bin/perl

my $input = join '', <STDIN>;
my $regexp = '.*\n(.*?Zeile1.*?\n).*\n(.*?Zeile2.*?\n).*\n(.*?Zeile3.*?\n)';

if ($input =~ /$regexp/s) { print $3, $1, $2; }
else { print "Unable to parse input\n"; }

etwa als wolfgangsunordnung.pl, ausführbar machen und schließlich
ausführen:

$ echo -e foo\\nbar\\nZeile1\\nbaz\\nZeile2\\nboing\\nZeile3\\nbingo\\n |\
wolfgangsunordnung.pl
Zeile3
Zeile1
Zeile2

Wobei dieses echo Deine Befehlsausgabe darstellen soll. Für mehr
Flexibilität könnte man den regulären Ausdruck und die Ordnung der
Ausgabe an der Kommandozeile übergeben.

Obige Lösung hat den Vorteil keine temporäre Datei zu benötigen und nur
einmal über die Eingabe zu rennen.

Tobias Nissen

unread,
Nov 18, 2009, 12:37:36 PM11/18/09
to
Tobias Nissen wrote:
[Ausgabe anhand von Regeln umordnen]

> Für mehr
> Flexibilität könnte man den regulären Ausdruck und die Ordnung der
> Ausgabe an der Kommandozeile übergeben.

Da mir auch ein Anwendungsfall dafür eingefallen ist, habe ich das mal
ausformuliert. Du kannst es unter http://paste.debian.net/51830/
herunterladen. Ist natürlich nur provisorisch das ganze, also schlechte
Hilfe und keine Kollisionsab^WÜberprüfung der Eingabe. Beispielaufruf:

$ echo -e foo\\nbar | reorder -r "(.*\n)(.*\n)" -o 21
bar
foo

Message has been deleted
0 new messages