[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: mal wieder: awk und regExpes



On 2004.03.15 12:55, Gebhard Dettmar wrote:
Andreas Schmidt scribbled on Sunday, March 14, 2004 9:50 PM

> AWK patterns may be one of the following:
>               /regular expression/
>               ! pattern
Versteh ich nicht. regular expression ist doch z.B. [^artikel[_d]]
Zudem habe ich hier ein Buch: Helmut Herold, sed und awk (2.Aufl.)
Bonn, Paris u.a.:Addison-Wesley 1994, S. 37 und passim:
[^a-z] deckt ein Zeichen ab, wenn dieses kein Kleinbuchstabe ist

AWK-Programme/Scripte/was_auch_immer sind, grob gesagt, nach dem Muster
  PATTERN: ANWEISUNG
aufgebaut; erfuellt eine Zeile die Bedingung PATTERN, wird die
entsprechende Anweisung ausgefuehrt. PATTERN _kann_ eine blosse regular
expression sein, muss es aber nicht. Hier nochmal eine komplette Liste
der Moeglichkeiten, die awk kennt (siehe man awk):
AWK patterns may be one of the following:
             BEGIN
             END
             /regular expression/
             relational expression
             pattern && pattern
             pattern || pattern
             pattern ? pattern : pattern
             (pattern)
             ! pattern
             pattern1, pattern2

Im ersten Beispiel ist der Ausdruck halbwegs (dazu spaeter mehr)
korrekt:
  awk '/artikel[_d]/{print "ARTIKEL",$2}' regexpr.txt >regartikel
Es gibt (willkuerlich ausgewaehlt) einige Zeilen, in denen der String
"artikel[_d]" gefunden wird, zB:
  UML \/cp_artikel\.htm\?artikel_id=117
  WEB_SCW_D \/cp_artikel_d\.htm\?artikel_id=109
Entsprechend werden die Daten auch in die Dateil regartikel
geschrieben.

Ich schrieb vorhin, dass der Ausdruck halbwegs korrekt sei. Damit
meinte ich, dass die Suche nach diesem Ausdruck Treffer ergibt, Du aber
nicht nach dem suchst, was Du eigentlich finden willst.

man awk zeigt unter "Regular expressions" folgendes:
  [abc...]   character list, matches any of the characters abc....
  (r)        grouping: matches r.

Ich nehme an, Du wolltest mit /artikel[_d]/ sowohl "artikel" als auch
"artikel_d" finden. /artikel/ haette dafuer schon voellig ausgereicht.
Man kann es sich aber natuerlich auch komplizierter machen, als es
unbedingt noetig waere. Die Variante mit [_d] ist aber nur bedingt zu
empfehlen: [_d] sucht naemlich nur nach einem Zeichen aus der Liste
(entweder "_" oder "d", aequivalent zu [d_]), nicht nach der Zeichenkette "_d". Dafuer ist (_d) zustaendig. "/artikel(_d)/ " wuerde aber die Zeilen, in denen nur "artikel" steht, ausblenden. "/artikel(_d)*/" bezieht diese Zeilen mit
ein, weil durch das nachgestellte * der vorhergehende Ausdruck als
optional gekennzeichnet wird (0 oder mehr Treffer erforderlich).

Die falsche Annahme, dass [AUSDRUCK] == (AUSDRUCK), setzt sich in
Deiner zweiten Variante fort und fuehrt zur Eskalation:
awk '/[^artikel[_d]]/{print "NAV",$2}' regexpr.txt >regnav
Hier suchst Du nach Zeilen, die die einzelnen Zeichen enthalten, die nicht in der Liste ("a", "r", "t", "i",...) stehen, nicht aber nach der gesamten Zeichenkette.


> awk '! artikel[_d] {print "NAV",$2}' regexpr.txt > regnav
> bringt also das gewuenschte ERgebnis.
Hmm, bei mir matcht er alle. Ich sitze hier aber auf Arbeit an einem
Win2K-Rechner mit einer Korn-shell von uwin (AT&T), der ich langsam
zu
misstrauen anfange. Muss das zu Hause mal mit debian und bash
probieren

Hmm, hatte gestern alles ausprobiert und war mir deshalb sicher, den
Fehler gefunden zu haben. War allerdings spaet, deshalb habe ich wohl
auch gepfuscht und bin erst eben nach langer Sucherei auf die Loesung
gestossen.
Ich bleibe  immer noch dabei, dass Dein Ansatz "/[^artikel[_d]]/"
verkehrt ist. Mein Fehler war, mit "! artikel[_d]" nach dem Wert einer
Variablen zu fragen; da diese nicht gesetzt ist, ist ihre Negation
immer wahr, demnach wird fuer jede Zeile die Anweisung ausgefuehrt.
Korrekterweise haette ich nach einer (negierten) Zeichenkette suchen
muessen, also:
  awk '! /artikel/ {print "NAV",$2}' regexpr.txt > regnav
oder, um alles komplizierter zu machen:
  awk '! /artikel(_d)*/ {print "NAV",$2}' regexpr.txt > regnav

So, ich hoffe mal, dass dieses Posting etwas hilfreicher war als das
letzte.

Schoenen Gruss,

Andreas



Reply to: