PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : awk Dateien verarbeiten



Hans-Georg Normann
07-10-2004, 20:37
habe zwar schon mit awk gearbeitet, den aber mehr oder weniger als Interpreter genutzt :mad: , weil ich unter UNIX kein Basic habe, zumindest nicht auf der Maschine.

Jetzt habe ich die Aufgabe, aus Uniplex-Dateien die Steuersymbole (Druckeffekte, Seitenumbrüche, Tabulatoren, etc.) zu entfernen, so dass eine normale Textdatei übrig bleibt.


####Tabulatoren Beispiele
L....T..........T.......T.........
...L...T...........T.....C......T..........R

##### Druckeffekt Beispiel
Hier steht sinnvoller Text@@
UUUU BBBBBBBBBB

##### Steuerbefehl Beispiele
.SN #64
.SL 66
.PL

Der Aufbau ist eigentlich ganz simpel.

Tabulatoren beginnen immer am Zeilenanfang. Mögliche Zeichen von Tabulatoren sind L, T, R, C, F und Punkt
Steuerbefehle beginnen immer am Zeilenanfang, beginnen immer mit einem Punkt gefolgt von mindestens zwei Großbuchstaben.
Steuertbefehle und Tabulatoren sind die einzigsten Einträge der Zeile, es folgt also kein Text.
Druckeffekte erkennt man am einleitenden @@. Dieses steht immer am Ende der Zeile. Die darauffolgende Zeile enthält die eigentlichen Effekte und sonst nichts.
mit find . -name "99-[0-9]*" -print bekomme ich die Dateien angezeigt, also müsste mit

find . -name "99-[0-9]*" -exec awk -f skript.awk {} \;
die eigentliche Verarbeitung gestartet werden können. Aber was muß in script.awk stehen? Das ist mein Problem.

Das ganze sollte dann noch als Datei mit der Endung .txt abgespeichert werden, aber das ist wohl das kleinste Problem.

Bin für jede Starthilfe dankbar.

Hans

peschmae
07-10-2004, 21:18
Ich würde das jetzt mit Sed machen. Aber das ist wohl auch kein Problem, oder?
Nein, zwar, grep genügt wohl schon.



Tabulatoren beginnen immer am Zeilenanfang. Mögliche Zeichen von Tabulatoren sind L, T, R, C, F und Punkt


die Regexp ist sowas:
[.LTRCF]



Steuerbefehle beginnen immer am Zeilenanfang, beginnen immer mit einem Punkt gefolgt von mindestens zwei Großbuchstaben.


\.[A-Z][A-Z][A-Z]*



Druckeffekte erkennt man am einleitenden @@. Dieses steht immer am Ende der Zeile. Die darauffolgende Zeile enthält die eigentlichen Effekte und sonst nichts.


Da muss man schon schwereres Geschütz auffahren. Blöde nächste Zeile. Irgend eine Sed-Lösung. Gucke ich morgen mal (oder übermorgen) falls du das brauchst und sich nichts einfacheres findet.

*Ideehab*:
@@\n*
geht zumindest scheinbar mit grep -v @@\n* - obs mit -e @@\n* auch geht - k.A., evtl brauchst du -e @@\n.*

Alles jeweils mit grep -v, also


grep -v -e '[.LTRCF]' -e '\.[A-Z][A-Z][A-Z]*' -e '@@\n*'


Ist aber ungetestet (wie verlangt nur ein Ansatz ;))

MfG Peschmä

Hans-Georg Normann
07-10-2004, 22:20
sed ist auch kein Problem. Dachte mir nur, dass awk flexibler ist, sprich das script leicht erweiterbar ist.

Wenn ich den Dateinamen in einer Umgebungsvariable speichern würde, und awk anweisen würde /dev/null mit dem script.awk zu bearbeiten, dann wüsste ich wie ich es anstelle. Das ist aber genau das, was ich als "script interpreter" bezeichne. Ich weiß, dass man das auch anders machen kann. Ich kenne aber leider (noch) keinen, der weiß wie es geht. Soll halt auch ein Lerneffekt bei sein.

Wenn ich mit sed arbeite dann müßte ich mit
1,$g/@@$/+1d
1,$s/@@$// das Problem doch in den griff bekommen, oder hält sich sed nicht an die vorgegeben Hirarchie.

Hans

peschmae
08-10-2004, 13:10
Was willst du mit /dev/null anstellen?
Den Sed-Code peil ich auch gar nicht.

MfG Peschmä

Hans-Georg Normann
08-10-2004, 21:15
Den Sed-Code peil ich auch gar nicht.OK, da sind die Pferde mit mir durchgegangen. Habe bereits gemerkt, dass sed!=vi ist.


Was willst du mit /dev/null anstellen?Wenn ich den awk als Interpreter missbrauche, dann geht's auch mit /dev/null. Ohne Fileangabe geht's nicht.

Ich habe mich jetzt nocheinmal hingesetzt und erst mal nach alter Gewohnheit was zurechtgezimmert. Das ist bis jetzt dabei herausgekommen:

Ich habe eine Datei file.list, in der alle dateien verzeichnet sind. Wie ich die (richtig) in awk einbinde, habe ich noch nicht herausbekommen.

Dann gibt es ein bash script, welches das ganze ausführt. Die Variable UAPFILE ist ein Notbehelf, aber damit habe ich das ersteinmal zum Laufen gebracht.

#!/usr/bin/bash

export UAPFILE=99-45783

#awk -f uniplex2text.awk /dev/null
awk -f uniplex2text.awk file.list ind hier das awk script
BEGIN {
System_Init()
Uniplex_Convert()
exit 0
}

function System_Init() {
false=0
true=!false
UAPFILE=ENVIRON["UAPFILE"]
TEXTFILE=(UAPFILE ".txt")
}

function Uniplex_Convert() {
EFFECT=false

while (getline < UAPFILE > 0) {
TEXT=$0
if (EFFECT) {
EFFECT=false
continue
}

MATCH=substr(TEXT,length(TEXT)-1)
print ("MATCH=" MATCH)
if (MATCH == "@@") {
TEXT=substr(TEXT,1,length(TEXT)-1)
EFFECT=true
print TEXT > TEXTFILE
continue
}

print TEXT > TEXTFILE
}

close(UAPFILE)
close(TEXTFILE)
} Liefert brauchbares, auch wenn ich mit "der harten Nuss" angefangen habe. Der Rest sollte auch gehen.

Upload scheint nicht zu gehen, aber wer Interesse hat kann sich die Datei hier (http://www.normann-live.de/Test/uniplex2text.tar.gz) downloaden. ca. 1 kB gross.

Hans

Hans-Georg Normann
09-10-2004, 14:27
Ist ja eigentlich gaaaanz einfach und ich war auch schon gaaanz nah dran. Also in das BEGIN kommen nur Sachen rein, die vor Scriptverarbeitung bekannt sein sollten. Außer true und false habe ich d jetzt nichts mehr stehen.

und dann legt man mit seinen Regexpressions los. Immer Regexpression {Befehle oder Funktion}. Ich habe als Regexpression // { eingebaut. Das bedeuted, dass die jeweils aus file.list gelesene Zeile in $0 wiederzufinden ist. Im Klartext sieht das jetzt so aus
BEGIN {
System_Init()
}

// {
UAPFILE=$0
TEXTFILE=(UAPFILE ".txt")
fTIME=strftime("%T %Z")
printf "%s: converting file: %s\n", fTIME, $0
Uniplex_Convert()
} Der Rest ist mit dem Code aus den vorigen Posts identisch. Und wie immer, wer will kann sich den Code hier (http://www.normann-live.de/Test/uniplex2text_v1.tar.gz) ziehen. Nicht mal 1 kb, sollte auch Einsteiger nicht überfordern.

Meine Probleme betrachte ich damit als gelöst, denn der Rest ist jetzt nur noch Fleißarbeit. :D

Hans