2010-12-31 8 views
1

ich viele Dateien mit Variablen in ihnen wieawk und Extrahieren von bestimmten Feld mehr als einmal

{$var1} some text {$var2} some other text 

haben würde Ich mag sie geben, damit awk awk extrahiert sie und gibt ein Ergebnis wie folgt aus:

file_name.htm - 8 : {$title} 
file_name.htm - 10 : {$css_style} 
file_name.htm - 33 : {$img_carte_image_02_over} 

Dies ist ein Stück des Kuchens mit diesem awk-Skript:

#!/usr/bin/gawk -f 
BEGIN { } 
match($0, /({.*\$.+})/, tab) { 
    for (x=1; tab[x]; x++) { 
    print FILENAME" - "FNR" : "substr($0, tab[x, "start"], tab[x, "length"]) 
    } 
} 
END { } 

ich es so nennen:

find website/ | grep -E '(html|htm)$' | xargs ./myh.sh | more 

Alles funktioniert gut, außer wenn mehrere Variablen in derselben Zeile sind. In diesem Fall erhalte ich:

file_name.htm - 59 : {$var1}<br/>{$var2} 

während ich will:

file_name.htm - 59 : {$var1} 
file_name.htm - 59 : {$var2} 

Irgendeine Idee, wie ich könnte/tun sollte? Natürlich, wenn Sie eine andere Lösung (mit sed oder was auch immer) haben, ist es in Ordnung für mich!

Vielen Dank!

+0

Könnten Sie ein Beispiel für die Awk-Eingabezeilen posten (eine gute, eine schlechte zumindest)? –

+0

Das Array, das 'match' füllt, enthält einen Eintrag für jede erfasste Gruppe'() 'und nicht jeden Teilstring, mit dem die Regex übereinstimmt. In Ihrem Fall entspricht es tatsächlich den meisten Zeilen, weil die Regex gierig ist. Siehe die Regex in Marcos Antwort für eine Technik, um es zu verankern. Beachten Sie, dass Sie, wenn Sie nichts in 'BEGIN' und' END' machen, diese weglassen können. –

Antwort

2

Versuchen Sie dieses:

awk '{ 
    line=$0; 
    while (match(line,/({[^$]*\$[^}]+})/)){ 
     print FILENAME,"-",FNR,":",substr(line,RSTART,RLENGTH); 
     line=substr(line,RSTART+RLENGTH+1) 
    } 
}' 

Der Zyklus endet, wenn match() 0 zurückgibt, dh, wenn die Leitung nicht andere "{$ foo bar}" enthält Strings; Ich habe substr() verwendet, um den Teil der Zeile zu entfernen, der bereits nach Übereinstimmungen durchsucht wurde.

+0

Vielen Dank in der Tat hat es wie ein Charme gearbeitet! –

0

Versuchen Sie es mit einem nicht-gierigen Regex im Spiel (http://www.exampledepot.com/egs/java.util.regex/Greedy.html). Wahrscheinlich wird nicht funktionieren, aber nur eine Idee.

+0

AWK weiß nicht, wie man nicht gierig macht. –