PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [BASH] String aus bestimmter Zeilenposition abgreifen?



mrt181
09-02-2009, 09:52
Hallo,

ich möchte einen String der in jeder Zeile einer Datei vorkommt nur an einer bestimmte Stelle in der Zeile abgreifen und die Zeilen dann in einzelne Dateien schreiben:

Beispiel Datei:

TESTTESTTEST#000#12345000000101 2009-01-01
TESTTESTTEST#000#12101000000101 2009-01-01

Mein Ansatz:

for i in {101..999}; do ??? > Datei_$i.txt; done

Ich will also den String aus Position 29 bis 31 abgreifen und die Zeile in eine eigene Datei schreiben. Mit grep funktioniert das leider nicht, da grep mir auch die 101 aus Position 20 bis 22 aus der 2. Zeile abgreifen würde. Mit cut kann ich zwar auf die entsprechenden Positionen reduzieren aber dann kann ich den Zeileninhalt nicht mehr in die Datei schreiben.

Es geht bestimmt mit awk, welches ich leider bisher kaum beherrsche. Ich kann mit awk auf die Position beschneiden, hilft mir aber nicht, da das nicht funktioniert:

grep $(awk '{print substr($0,29,3)}' Datei.txt) Datei.txt > Datei_$i.txt
Kann ja auch nicht funktionieren, da awk mehrere Werte zurückgibt.

ContainerDriver
09-02-2009, 10:11
Hallo,

eventuell funktioniert es so (ungetestet):


for line in `cut -b 29-31 <datei>`; do
echo $line >> Datei_$line;
done;


Gruß, Florian

EDIT: hier noch eine Lösung mit awk (die wahrscheinlich stabiler läuft):


awk '{num=substr($0, 29,3); print num >> sprintf("%s_%d", "Datei", num)}' <file>

mrt181
09-02-2009, 10:57
die awk lösung funktioniert gut, gibt aber nur den string aus position 29 bis 32 wieder aber nicht die ganze zeile. Das gleiche bei der for schleife.

ContainerDriver
09-02-2009, 11:11
Sorry, hab deine Frage zu ungenau gelesen. :o

Der awk-Aufruf müsste dann so aussehen:


awk '{num=substr($0, 29,3); print $0 >> sprintf("%s_%d", "Datei", num)}' <file>


und das ganze ohne awk:


cat <file>|while read line; do echo $line>>Datei_`echo $line|cut -b 29-31 -`; done;


Mit deinem Ansatz von oben könnte man das so lösen:


for i in {101..999}; do grep '.\{28,\}101.*' <file> > Datei_$i.txt; done
.

Gruß, Florian

mrt181
09-02-2009, 11:21
Super, vielen Dank. awk ist am schnellsten, mein von dir modifizierter Ansatz funktioniert nicht