Viiieeele files eines directories nach bestimmten Daten scannen
Liebe bash-grep-sed-awk-???-Profis! ich habe hier ein Problem zu lösen, bin aber nicht so gewandt in der Verwendung der Linux tools wie es dafür nötig wäre: In einem Directory habe ich viele (ca. 4000) XML Dateien, die alle den gleich strukturierten Inhalt haben. Die Dateinamen sind nach dem Muster YYYYMMDDHHMMSSnnnnn.xml aufgebaut. Der Inhalt der Dateien ist ein xml formatierter stream, soweit ich es bereits untersucht habe OHNE CR/LF am Ende. Die Dateien sind unterschiedlich groß, die kleinste 3 KB, die (bis jetzt) Größte 215 KB Der Aufbau ist immer der Selbe: ........................................<timestamp>YYYY-MM-DDTHH:MM:SS</timestamp>...........................<value>nnnnn</value>........................ wobei "." für alles steht, das mich NICHT interessiert. Mich interessiert ausschließlich der Timestamp und die numerische Value. Beide kommen pro Datei nur 1x vor (ziemlich gegen Ende). Ich hätte nun gerne "etwas" (scipt, Kommando, mehrere Kommandos ...) durch das ich einen Teil der Dateien "durchschicken" kann (z.B. für die von heute "20180701*xml") und das mir dann folgenden output liefert: YYYY-MM-DDTHH:MM:SS nnnnn\n YYYY-MM-DDTHH:MM:SS nnnnn\n YYYY-MM-DDTHH:MM:SS nnnnn\n YYYY-MM-DDTHH:MM:SS nnnnn\n usw... Oder anders ausgedrückt: jede datei lesen, alles ignorieren bis der timestamp kommt, diesen ausgeben, weiterlesen bis die value kommt, diese ausgeben, Ein linefeed anhängen Ich könnte mich jetzt hinsetzen und das ganze in C programmieren. Oder in C++ mit den Qt Klassen einen XML parser basteln. Aber ich denke mir, das muss doch einfacher mit den vorhandenen shell-tools gehen.. Nur, ich kriegs einfach nicht hin... Ich weiß, hier gibt es eine Menge shell-programming-grep-awk-usw Gurus.. Hat wer von Euch einen Tip ? Grüße Norbert -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
Hallo Norbert, for d in 20180701*xml ; do ts=$(grep -Po '<timestamp>.*</timestamp>' $d | sed -E -e 's/<.?timestamp>// g') value=$(grep -Po '<value>.*</value>' $d | sed -E -e 's/<.?value>//g') echo "$ts $value" done gruß Harald Am Sonntag, 1. Juli 2018, 01:35:24 CEST schrieb Norbert Zawodsky:
Liebe bash-grep-sed-awk-???-Profis!
Der Aufbau ist immer der Selbe:
........................................<timestamp>YYYY-MM-DDTHH:MM:SS...........................<value>nnnnn</value>....................... .
wobei "." für alles steht, das mich NICHT interessiert. Mich interessiert ausschließlich der Timestamp und die numerische Value. Beide kommen pro Datei nur 1x vor (ziemlich gegen Ende).
Ich hätte nun gerne "etwas" (scipt, Kommando, mehrere Kommandos ...) durch das ich einen Teil der Dateien "durchschicken" kann (z.B. für die von heute "20180701*xml") und das mir dann folgenden output liefert:
YYYY-MM-DDTHH:MM:SS nnnnn\n YYYY-MM-DDTHH:MM:SS nnnnn\n YYYY-MM-DDTHH:MM:SS nnnnn\n YYYY-MM-DDTHH:MM:SS nnnnn\n
usw...
Oder anders ausgedrückt:
jede datei lesen, alles ignorieren bis der timestamp kommt, diesen ausgeben, weiterlesen bis die value kommt, diese ausgeben, Ein linefeed anhängen
Ich könnte mich jetzt hinsetzen und das ganze in C programmieren. Oder in C++ mit den Qt Klassen einen XML parser basteln. Aber ich denke mir, das muss doch einfacher mit den vorhandenen shell-tools gehen.. Nur, ich kriegs einfach nicht hin...
Ich weiß, hier gibt es eine Menge shell-programming-grep-awk-usw Gurus.. Hat wer von Euch einen Tip ?
Grüße Norbert
-- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
Hallo Harald, hallo Norbert, hallo zusammen, Am Sonntag, 1. Juli 2018, 08:35:26 CEST schrieb Harald Stürmer:
for d in 20180701*xml ; do ts=$(grep -Po '<timestamp>.*</timestamp>' $d | sed -E -e 's/<.?timestamp>// g') value=$(grep -Po '<value>.*</value>' $d | sed -E -e 's/<.?value>//g') echo "$ts $value" done
Das sieht schonmal gut aus, startet aber zu viele Prozesse ;-) (Faustregel: sed kann auch greppen, daher brauchst Du kein extra grep) Wenn <timestamp> und <value> zusammen in einer Zeile stehen, kannst Du alles in einen sed-Befehl zusammenfassen: for d in 20180701*xml ; do sed -n 's/^.*<timestamp>\([0-9:-]*\)<\/timestamp>.*<value>\([0-9]*\)<\/value>.*$/\1 \2/p' < "$d" done Zum Testen: # (echo foo; echo '....................................<timestamp>YYYY-MM-DDTHH:MM:SS</timestamp>...........................<value>nnnnn</value>.................' ; echo bar ) | sed -n 's/^.*<timestamp>\([A-Z0-9:-]*\)<\/timestamp>.*<value>\([n0-9]*\)<\/value>.*$/\1 \2/p' YYYY-MM-DDTHH:MM:SS nnnnn (Damit der sed-Befehl mit den Dummy-Daten funktioniert, erlaubt die Regex auch "A-Z" bzw. "n". Für den Produktiv-Befehl in der Schleife habe ich die schon entfernt.) Falls <timestamp> und <value> in getrennten Zeilen stehen (können), ist die langweiligste Lösung, den sed-Befehl auf zwei Befehle aufzusplitten (einer für jeden Tag) - wobei "langweilig" was anderes ist als optimal ;-) Wenn Du noch mehr mit dem XML anstellen willst, wirst Du irgendwann an die Grenze regulärer Ausdrücke kommen - irgendwann schmerzt die "richtige" XML-Verarbeitung (z. B. mit XLST) weniger als RegEx-Magie ;-) Gruß Christian Boltz PS: Keine Zufallssignatur ;-) -- In most cases, XSLT is good enough. But I agree, for some parts you need Aspirin. ;-) [Thomas Schraitle in opensuse-doc] -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
On So, 01 Jul 2018, Norbert Zawodsky wrote:
Liebe bash-grep-sed-awk-???-Profis!
ich habe hier ein Problem zu lösen, bin aber nicht so gewandt in der Verwendung der Linux tools wie es dafür nötig wäre:
In einem Directory habe ich viele (ca. 4000) XML Dateien, die alle den gleich strukturierten Inhalt haben. Die Dateinamen sind nach dem Muster YYYYMMDDHHMMSSnnnnn.xml aufgebaut. Der Inhalt der Dateien ist ein xml formatierter stream, soweit ich es bereits untersucht habe OHNE CR/LF am Ende. Die Dateien sind unterschiedlich groß, die kleinste 3 KB, die (bis jetzt) Größte 215 KB
Der Aufbau ist immer der Selbe:
........................................<timestamp>YYYY-MM-DDTHH:MM:SS</timestamp>...........................<value>nnnnn</value>........................
wobei "." für alles steht, das mich NICHT interessiert. Mich interessiert ausschließlich der Timestamp und die numerische Value. Beide kommen pro Datei nur 1x vor (ziemlich gegen Ende).
Ich hätte nun gerne "etwas" (scipt, Kommando, mehrere Kommandos ...) durch das ich einen Teil der Dateien "durchschicken" kann (z.B. für die von heute "20180701*xml") und das mir dann folgenden output liefert:
YYYY-MM-DDTHH:MM:SS nnnnn\n YYYY-MM-DDTHH:MM:SS nnnnn\n YYYY-MM-DDTHH:MM:SS nnnnn\n YYYY-MM-DDTHH:MM:SS nnnnn\n
usw...
Oder anders ausgedrückt:
jede datei lesen, alles ignorieren bis der timestamp kommt, diesen ausgeben, weiterlesen bis die value kommt, diese ausgeben, Ein linefeed anhängen
Ich könnte mich jetzt hinsetzen und das ganze in C programmieren. Oder in C++ mit den Qt Klassen einen XML parser basteln. Aber ich denke mir, das muss doch einfacher mit den vorhandenen shell-tools gehen.. Nur, ich kriegs einfach nicht hin...
Ich weiß, hier gibt es eine Menge shell-programming-grep-awk-usw Gurus.. Hat wer von Euch einen Tip ?
Für xml sollte man doch was spezielles nehmen und nicht mit regexp rumfuschen :) xmlstarlet sel -I -t -v "//timestamp" -o " " -v "//value" *.xml Best, Christian -- Der Weise rechnet das Mißvergnügen zu seinen Sünden. -- Jean Paul -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
Am 2018-07-14 19:59 schrieb Christian Brabandt:
On So, 01 Jul 2018, Norbert Zawodsky wrote:
Liebe bash-grep-sed-awk-???-Profis!
ich habe hier ein Problem zu lösen, bin aber nicht so gewandt in der Verwendung der Linux tools wie es dafür nötig wäre:
In einem Directory habe ich viele (ca. 4000) XML Dateien, die alle den gleich strukturierten Inhalt haben. Die Dateinamen sind nach dem Muster YYYYMMDDHHMMSSnnnnn.xml aufgebaut. Der Inhalt der Dateien ist ein xml formatierter stream, soweit ich es bereits untersucht habe OHNE CR/LF am Ende. Die Dateien sind unterschiedlich groß, die kleinste 3 KB, die (bis jetzt) Größte 215 KB
Der Aufbau ist immer der Selbe:
........................................<timestamp>YYYY-MM-DDTHH:MM:SS</timestamp>...........................<value>nnnnn</value>........................
wobei "." für alles steht, das mich NICHT interessiert. Mich interessiert ausschließlich der Timestamp und die numerische Value. Beide kommen pro Datei nur 1x vor (ziemlich gegen Ende).
Ich hätte nun gerne "etwas" (scipt, Kommando, mehrere Kommandos ...) durch das ich einen Teil der Dateien "durchschicken" kann (z.B. für die von heute "20180701*xml") und das mir dann folgenden output liefert:
YYYY-MM-DDTHH:MM:SS nnnnn\n YYYY-MM-DDTHH:MM:SS nnnnn\n YYYY-MM-DDTHH:MM:SS nnnnn\n YYYY-MM-DDTHH:MM:SS nnnnn\n
usw...
Oder anders ausgedrückt:
jede datei lesen, alles ignorieren bis der timestamp kommt, diesen ausgeben, weiterlesen bis die value kommt, diese ausgeben, Ein linefeed anhängen
Ich könnte mich jetzt hinsetzen und das ganze in C programmieren. Oder in C++ mit den Qt Klassen einen XML parser basteln. Aber ich denke mir, das muss doch einfacher mit den vorhandenen shell-tools gehen.. Nur, ich kriegs einfach nicht hin...
Ich weiß, hier gibt es eine Menge shell-programming-grep-awk-usw Gurus.. Hat wer von Euch einen Tip ? Für xml sollte man doch was spezielles nehmen und nicht mit regexp rumfuschen :)
xmlstarlet sel -I -t -v "//timestamp" -o " " -v "//value" *.xml
Best, Christian
Hallo Christian, also, als "rumpfuschen" würde ich grep, sed & Co nicht bezeichnen. Aber danke für den Hinweis auf xmlstarlet!! Kannte ich nicht, werde ich gleich mal unter die Lupe nehmen. Grüße, Norbert -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
Am 2018-07-14 21:20 schrieb Norbert Zawodsky:
Am 2018-07-14 19:59 schrieb Christian Brabandt:
On So, 01 Jul 2018, Norbert Zawodsky wrote:
Liebe bash-grep-sed-awk-???-Profis!
ich habe hier ein Problem zu lösen, bin aber nicht so gewandt in der Verwendung der Linux tools wie es dafür nötig wäre:
In einem Directory habe ich viele (ca. 4000) XML Dateien, die alle den gleich strukturierten Inhalt haben. Die Dateinamen sind nach dem Muster YYYYMMDDHHMMSSnnnnn.xml aufgebaut. Der Inhalt der Dateien ist ein xml formatierter stream, soweit ich es bereits untersucht habe OHNE CR/LF am Ende. Die Dateien sind unterschiedlich groß, die kleinste 3 KB, die (bis jetzt) Größte 215 KB
Der Aufbau ist immer der Selbe:
........................................<timestamp>YYYY-MM-DDTHH:MM:SS</timestamp>...........................<value>nnnnn</value>........................
wobei "." für alles steht, das mich NICHT interessiert. Mich interessiert ausschließlich der Timestamp und die numerische Value. Beide kommen pro Datei nur 1x vor (ziemlich gegen Ende).
Ich hätte nun gerne "etwas" (scipt, Kommando, mehrere Kommandos ...) durch das ich einen Teil der Dateien "durchschicken" kann (z.B. für die von heute "20180701*xml") und das mir dann folgenden output liefert:
YYYY-MM-DDTHH:MM:SS nnnnn\n YYYY-MM-DDTHH:MM:SS nnnnn\n YYYY-MM-DDTHH:MM:SS nnnnn\n YYYY-MM-DDTHH:MM:SS nnnnn\n
usw...
Oder anders ausgedrückt:
jede datei lesen, alles ignorieren bis der timestamp kommt, diesen ausgeben, weiterlesen bis die value kommt, diese ausgeben, Ein linefeed anhängen
Ich könnte mich jetzt hinsetzen und das ganze in C programmieren. Oder in C++ mit den Qt Klassen einen XML parser basteln. Aber ich denke mir, das muss doch einfacher mit den vorhandenen shell-tools gehen.. Nur, ich kriegs einfach nicht hin...
Ich weiß, hier gibt es eine Menge shell-programming-grep-awk-usw Gurus.. Hat wer von Euch einen Tip ? Für xml sollte man doch was spezielles nehmen und nicht mit regexp rumfuschen :)
xmlstarlet sel -I -t -v "//timestamp" -o " " -v "//value" *.xml
Best, Christian
Hallo Christian,
also, als "rumpfuschen" würde ich grep, sed & Co nicht bezeichnen.
Aber danke für den Hinweis auf xmlstarlet!! Kannte ich nicht, werde ich gleich mal unter die Lupe nehmen.
Grüße, Norbert
Cool tool !! Genial. Super. Danke für den Hinweis! Grüße, Norbert -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
participants (4)
-
Christian Boltz
-
Christian Brabandt
-
Harald Stürmer
-
Norbert Zawodsky