linuxbasher
Anmeldungsdatum: 6. März 2010
Beiträge: 44
|
Hallo zusammen! Ich möchte Tabellen im Textformat (hier "csv"-Dateien von OpenOffice) mit bash (oder awk oder perl) weiter bearbeiten. Jede Zeile enthält mehrere Felder, die durch ein Trennzeichen wie z.B. ein Komma getrennt sind. Jedes Feld könnte das Trennzeichen selbst enthalten, weswegen es in Anführungszeichen eingeschlossen ist. Eine Zeile sieht wie folgt aus: "Meier, Heinz", "Straße", "12345 Stadt" Ich möchte solche Zeilen in ein Array einlesen. Mit (bash) read -d "," -a A geht es offensichtlich nicht, weil Anführungszeichen nicht berücksichtigt werden. Gibt es eine einfache und elegante Möglichkeit, solche Textzeilen in bash / awk / perl unter Berücksichtigung der Anführungszeichen korrekt zu parsen und in ein Array einzulesen? Grüße linuxbasher
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17608
Wohnort: Berlin
|
Geht das:
sed 's/", "/;/g' adr.csv | read -d ";" -a A
|
Lunar
Anmeldungsdatum: 17. März 2006
Beiträge: 5792
|
Ohne Perl zu kennen, bin ich mir vollkommen sicher, dass es in den unendlichen Weiten des CPAN ein oder mehrere Module zum Parsen von CSV-Dateien gibt. Einfach mal suchen … ☺
|
tzzaetaynzz
Anmeldungsdatum: 9. Mai 2009
Beiträge: 265
|
|
Hello_World
Anmeldungsdatum: 13. Juni 2006
Beiträge: 3620
|
linuxbasher schrieb: Hallo zusammen! Ich möchte Tabellen im Textformat (hier "csv"-Dateien von OpenOffice) mit bash (oder awk oder perl) weiter bearbeiten. Jede Zeile enthält mehrere Felder, die durch ein Trennzeichen wie z.B. ein Komma getrennt sind. Jedes Feld könnte das Trennzeichen selbst enthalten, weswegen es in Anführungszeichen eingeschlossen ist.
Und wenn das Feld Anführungszeichen enthält?
|
linuxbasher
(Themenstarter)
Anmeldungsdatum: 6. März 2010
Beiträge: 44
|
user unknown schrieb: Geht das:
sed 's/", "/;/g' adr.csv | read -d ";" -a A
Eigentlich nicht, weil auch keine saubere Lösung. Ich hatte mich vertan. Zeilen sehen aus wie folgt:
"Meier, Heinz","Straße","12345 Stadt" tzzaetaynzz schrieb: http://search.cpan.org/dist/Text-CSV/
Danke für den Hinweis. Die Seite kannte ich noch nicht. Das Modul scheint tatsächlich ein "Alleskönner" zu sein, allerdings nicht einfach zu bedienen. Ich lasse diesen Thread noch etwas offen, weil ich noch auf halbwegs einfache Tricks unter awk und bash warte. Ich benutze noch einen Workaround mit awk (Quotes entfernen, Doppelquotes durch einfache ersetzen usw.). Weil die bash selbst das Quoten gut beherrscht, habe ich auch mit Konstrukten wie declare -a A
eval "A=($zeile)" herumexperimentiert, aber die sind sehr gefährlich.
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Die große Unbekannte ist hier doch imho, was Du denn mit den Daten vorhast? Sollte das Problem zu komplex für die Bash sein, wieso dann nicht alles in Perl schreiben? Wo liegt hier der Vorteil der Bash?
|
Hello_World
Anmeldungsdatum: 13. Juni 2006
Beiträge: 3620
|
linuxbasher schrieb: Danke für den Hinweis. Die Seite kannte ich noch nicht. Das Modul scheint tatsächlich ein "Alleskönner" zu sein, allerdings nicht einfach zu bedienen.
Wie bitte!? Ich habe keinen Plan von Perl, und die Nutzung des Moduls ist nach einen kurzen Blick auf die Synopsis sonnenklar. Einfacher wird's nicht.
|
linuxbasher
(Themenstarter)
Anmeldungsdatum: 6. März 2010
Beiträge: 44
|
Lysander schrieb: Die große Unbekannte ist hier doch imho, was Du denn mit den Daten vorhast? Sollte das Problem zu komplex für die Bash sein, wieso dann nicht alles in Perl schreiben? Wo liegt hier der Vorteil der Bash?
Es ist ein eigenes Quick-and-(not-too)-dirty-Skript, mit dem ich mein Adressbuch von OpenOffice (als csv-Datei gespeichert) auslese, filtere und als einfache HTML-Seite nach meinem Gusto darstelle. Es ist recht einfach, funktioniert einwandfrei, ist aber halt nicht sauber programmiert. Da das Problem, des Quotens, des Escapens und des Parsens von csv-Dateien viel allgemeiner ist, wollte ich hier nur nach ein paar eleganten Programiertricks fragen, falls es die gibt. Perl mit dem genannten Modul oder einem selbst geschriebenen Parser ist mir hierfür etwas zu overkill.
|
Hello_World
Anmeldungsdatum: 13. Juni 2006
Beiträge: 3620
|
Nochmal: Dieses Modul ist absolut trivial zu benutzen. Wenn Dir das zu viel Aufwand ist, dann lass das Script wie es ist. Eine nennenswerte Verbesserung wird Dir dann nämlich ohnehin nicht gelingen.
|
Lunar
Anmeldungsdatum: 17. März 2006
Beiträge: 5792
|
Der eleganteste Programmiertrick ist hier, Perl mit diesem Modul zu nutzen, einfacher wird es nicht. Wenn Dir das zu "overkill" ist, kann Dir nicht mehr geholfen werden …
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Hi linuxbasher, noch Willkommen auf dem Forum ! Sind die Felder in Deiner csv immer in Gänsefüßchen gekapselt ? Und immer mit Komma getrennt, ohne Leerzeichen ? Dann würde es doch ausreichen, wenn Du awk einsetzt, und das Trennsymbol auf "," festlegst. Dann noch das " am Anfang und am Ende gelöscht, und die Felder stehen ganz brav in den Feldern $1, $2, usw. von awk ... ich glaube, so würde ich das machen. track
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
linuxbasher schrieb: Es ist ein eigenes Quick-and-(not-too)-dirty-Skript, mit dem ich mein Adressbuch von OpenOffice (als csv-Datei gespeichert) auslese, filtere und als einfache HTML-Seite nach meinem Gusto darstelle. Es ist recht einfach, funktioniert einwandfrei, ist aber halt nicht sauber programmiert.
Das würde mich reizen mal in Python3 mit jinja 2.3 zu realisieren ☺ Das geht sicher recht kurz und elegant...
|
Hello_World
Anmeldungsdatum: 13. Juni 2006
Beiträge: 3620
|
Ich hab gerade mal etwas zusammengestrickt. Mit Text::CSV und HTML::EasyTags ist das wirklich einfach.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | #!/usr/bin/perl
use strict;
use Text::CSV;
use HTML::EasyTags;
my $html = HTML::EasyTags->new();
my $csv = Text::CSV->new({binary => 1});
print $html->start_html('Mein Adressbuch');
print $html->table_start;
while (my $row = $csv->getline(\*STDIN)) {
print $html->tr_start;
foreach (@$row) {
print $html->td(text => $_);
}
print $html->tr_end;
}
print $html->table_end;
print $html->end_html;
|
Ordentlich geärgert habe ich mich aber heute über cpan(1) . Der Mist ist nicht in der Lage, Devel::REPL zu installieren und ist zudem der mit großem Abstand benutzerunfreundlichste Paketmanager, den ich kenne.
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
☺ Eine awk-Variante dazu habe ich da auch noch mal schnell zusammengestrickt:
#! /usr/bin/awk -f
### Skript csv2html konvertiert eine comma-separated list in eine einfache html-Tabelle
BEGIN { print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">";
print "<TABLE BORDER=2>";
}
{ sub("^\"","<TR><TD>",$0);
gsub("\",\"","</TD><TD>",$0);
sub("\"$","</TD></TR>",$0);
print $0;
}
END { print "</TABLE>"; } Das Skript muss natürlich erst "ausführbar" gemacht werden, (einfach per Rechtsklick - Eigenschaften - [Rechte] - [√] Ausführen) dann erfolgt der Aufruf mit:
./csv2html liste.csv > liste.html
track
- csv2html (358 Bytes)
- Download csv2html
|