ubuntuusers.de

multi_grep um Minusfunktion erweitern

Status: Gelöst | Ubuntu-Version: Ubuntu 14.04 (Trusty Tahr)
Antworten |

Tron0070

Avatar von Tron0070

Anmeldungsdatum:
22. März 2010

Beiträge: 195

Wohnort: Chemnitz

Hallo, ich würden gern das Skript um eine Minus-Funktion erweitern. Es soll also bei der Eingabe von:

> buch laden -geschäft

nur:

das geliehene Buch
Buchladen
Waffe geladen und gesichert

finden. Aber nicht:

Geschäft
geschäftstüchtig
Buchgeschäft

finden.

Die Rekursion von "rklm" erfüllt schon den ersten Teil. Leider weiß ich nicht wie ich da noch ein "grep -v" für "Nicht-passende Zeilen anzeigen" einbauen kann.

Es wäre schön, wenn jemand ein Idee hätte.

Gruß Tron

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
multi_grep() { 
    local w="$1"
    shift || return

    if [ $1 = -- ]; then
        shift
        fgrep --color=always -i -e "$w" "$@"
    else
        multi_grep "$@" | fgrep --color=always -i -e "$w"
    fi
}

multi_grep "${word_array[@]}" -- "${files[@]}"

Bearbeitet von sebix:

Ubuntu Mate 14.04 existiert nicht, auf Ubuntu geändert.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13207

Am einfachsten ist, wenn Du $w anschaust und eine Variable auf "-v" setzt, sobald das Wort mit einem Minus anfängt. Die Variable fügt man dann in die Kommandozeile hinter dem Pipe-Symbol ein. Und man muss das "-" natürlich aus dem Wort entfernen.

Tron0070

(Themenstarter)
Avatar von Tron0070

Anmeldungsdatum:
22. März 2010

Beiträge: 195

Wohnort: Chemnitz

hm. Ich weiß nicht wie. Das Problem ist, dass ich diese Funktion nie richtig verstanden habe. Kannst du das bitte für mich dort einbauen?

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13207

Tron0070 schrieb:

hm. Ich weiß nicht wie. Das Problem ist, dass ich diese Funktion nie richtig verstanden habe. Kannst du das bitte für mich dort einbauen?

Oh, jeh! Dann lernst Du aber auch nichts.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
multi_grep() { 
    local w="$1"
    shift || return

    local x="${w#-}"
    local v=''
    test "$x" = "$w" || v='-v'

    if [ $1 = -- ]; then
        shift
        fgrep --color=always -i $v -e "$x" "$@"
    else
        multi_grep "$@" | fgrep --color=always -i $v -e "$x"
    fi
}

Die ganze Sache hat allerdings noch einen Schönheitsfehler, wie ich gerade sehe: es werden auch Suchmuster in den Dateinamen gefunden. Der einfache Fall (also ohne Ausschlüsse) würde besser dadurch abgedeckt, dass Du alle Suchwörter in eine Datei packst und dann so aufrufst:

1
fgrep --color=always -i -f woerter.txt datei1 datei2 ...

Das ist nebenbei auch effizienter, weil es weniger IO gibt.

Tron0070

(Themenstarter)
Avatar von Tron0070

Anmeldungsdatum:
22. März 2010

Beiträge: 195

Wohnort: Chemnitz

Vielen Dank. Es funktioniert wunderbar. Und so langsam verstehe ich den Code auch, was für mich nicht gerade leicht ist, da ich bis jetzt nur simple Skripte gebaut habe.

Und der Effekt, dass der Dateiname gefunden wird tritt bei mir nicht auf.

Der Aufruf sieht bei mir so aus.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
if [ \! -e $pfad/suche ]; then
	touch $pfad/suche
fi

suche=`cat $pfad/suche`
read -e -i  "$suche" suche
echo $suche >$pfad/suche

word_array=($suche)

multi_grep "${word_array[@]}" -- "${files[@]}"

EDIT: Ich habe mich beim Dateinamen Effekt geirrt. Wenn ich z.B nur wenn ich nach "-dateiname" suchen würde, wird mir der Inhalt aller Dateien aufgelistet. Aber ich denke das ist nicht so schlimm, da so etwas nicht vorkommt.

Antworten |