Shellscript String zerschneiden

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
gnude
Beiträge: 1567
Registriert: 14.09.2009 22:05:28
Kontaktdaten:

Shellscript String zerschneiden

Beitrag von gnude » 22.08.2017 22:10:30

Hallo

ich möchte gerne einen String zerschneiden und die Leerzeichen durch ; ersetzten.
Allerdings muss ich den String von vorne und hinten abschneiden.
Problem ist....
Die ersten 2 Werte sind Fest, dann kann ein Bereich mit mehreren Worten kommen wo das Leerzeichen o ist und die letzten 6 Leerzeichen
sind wieder fix.

Zwei Beispiele

A B C Das ist der Text E F W F G

oder
A B C Das ist ein etwas längerer Text E F W F G

Der mittlere Text soll in seinem Feld. Es soll im prinzip eine CSV Datei herauskommen

A;B;C;Das ist der Text;E;F;W;F;G
A;B;C;Das ist ein etwas längerer Text;E;F;W;F;G

owl102

Re: Shellscript String zerschneide

Beitrag von owl102 » 22.08.2017 22:40:05

gnude hat geschrieben: ↑ zum Beitrag ↑
22.08.2017 22:10:30
Die ersten 2 Werte sind Fest, dann kann ein Bereich mit mehreren Worten kommen wo das Leerzeichen o ist und die letzten 6 Leerzeichen
sind wieder fix.
Bei deinen Beispielen sind es aber nicht 2+6, sondern 3+5 feste Werte/Leerzeichen.

Code: Alles auswählen

g='\([[:graph:]][[:graph:]]*\)'
sed -n "s/^$g $g $g \(.*\) $g $g $g $g $g\$/\1;\2;\3;\4;\5;\6;\7;\8;\9/p" testdatei 
klappt zumindest mit deinen beiden Beispielen.

Annahme: Die einzelnen Felder sind durch genau ein Leerzeichen getrennt. Ansonsten müsste man halt die Leerzeichen noch durch "[[:space:]][[:space:]]*" ersetzen.

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Shellscript String zerschneide

Beitrag von Meillo » 23.08.2017 07:52:57

@owl102: Da hast du aber Glueck gehabt, dass es nicht mehr als neun Felder sind. ;-)


Hier eine Alternative (in GNU awk), die auch mit groesseren Feldanzahlen funktioniert:

Code: Alles auswählen

#!/usr/bin/awk -f

{
        for (i=0; i<3; i++) {
                sub(/ /, ";");
        }
        for (i=0; i<5; i++) {
                $0 = gensub(/ /, ";", NF-1);
                # gensub() is a GNU awk extension
        }
        OFS = ";"
        print
}

Hier noch eine Variante (in portablem awk), die allerdings beliebigen Whitespace zu einfachen Spaces vereint, auch im Inhalt von Feld 4:

Code: Alles auswählen

#!/usr/bin/awk -f

{
        for (i=1; i<=NF; i++) {
                if (i == NF) {
                        sep = "\n"
                } else if (i <= 3 || i >= NF-5) {
                        sep = ";"
                } else {
                        sep = " "
                }
                printf("%s%s", $i, sep)
        }
}
Use ed once in a while!

owl102

Re: Shellscript String zerschneide

Beitrag von owl102 » 23.08.2017 09:17:09

Meillo hat geschrieben: ↑ zum Beitrag ↑
23.08.2017 07:52:57
Hier eine Alternative (in GNU awk), die auch mit groesseren Feldanzahlen funktioniert:
Tut nicht funktionieren tun, muddu nacharbeiten:

Code: Alles auswählen

$ cat testdatei
A B C Das ist der Text E F W F G
A B C Das ist ein etwas längerer Text E F W F G
A B C Dies  ist  ein  Test E F W F G
$ ./testscript testdatei
A;B;C;Das ist der Text;E;F;W;F;G
A;B;C;Das ist ein etwas längerer Text;E;F;W;F;G
A;B;C;Dies  ist  ein;;Test;E;F;W F G
Tja, meine Lösung mag ja nur mit (bis zu) 9 Feldern funktionieren (was im übrigen nicht Glück ist, sondern die vom Fragesteller vorgegebene Spezifikation), dafür funktioniert aber obriges Beispiel mit meiner Lösung. :mrgreen:

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Shellscript String zerschneide

Beitrag von Meillo » 23.08.2017 10:17:42

owl102 hat geschrieben: ↑ zum Beitrag ↑
23.08.2017 09:17:09
Meillo hat geschrieben: ↑ zum Beitrag ↑
23.08.2017 07:52:57
Hier eine Alternative (in GNU awk), die auch mit groesseren Feldanzahlen funktioniert:
Tut nicht funktionieren tun, muddu nacharbeiten:

Code: Alles auswählen

$ cat testdatei
A B C Das ist der Text E F W F G
A B C Das ist ein etwas längerer Text E F W F G
A B C Dies  ist  ein  Test E F W F G
$ ./testscript testdatei
A;B;C;Das ist der Text;E;F;W;F;G
A;B;C;Das ist ein etwas längerer Text;E;F;W;F;G
A;B;C;Dies  ist  ein;;Test;E;F;W F G
Da hast du Recht. Man ersetze die gensub()-Zeile durch diese:

Code: Alles auswählen

$0 = gensub(/[ \t]+/, ";", NF-1);
Tja, meine Lösung mag ja nur mit (bis zu) 9 Feldern funktionieren (was im übrigen nicht Glück ist, sondern die vom Fragesteller vorgegebene Spezifikation), dafür funktioniert aber obriges Beispiel mit meiner Lösung. :mrgreen:
Das Problem ist, dass es mit deinem Ansatz in sed(1) keine Moeglichkeit gibt, ein zehntes Feld zu addressieren. Das ist also kein Problem von hardgecodeten neun Feldern, sondern von einem Verfahren, das nur bis neun Felder moeglich ist. Darum hast du eben Glueck gehabt, dass es nur neun Felder waren. (Und meine Bemerkung ist wirklich mit diesem Augenzwinkern zu verstehen.) Aber nun gut, man muesste dann halt zwei s-Befehle nehmen: Einmal ein paar vordere Felder bearbeiten und danach die restlichen. Damit koennte man die Anzahl der Felder fast verdoppeln.

Ich finde uebrigens deine sed-Loesung besser als meine awk-Loesungen ... aber ich finde sie nicht so gut, dass es sich nicht lohnen wuerde weiter darueber nachzudenken. ;-)
Use ed once in a while!

owl102

Re: Shellscript String zerschneide

Beitrag von owl102 » 23.08.2017 21:58:51

Meillo hat geschrieben: ↑ zum Beitrag ↑
23.08.2017 10:17:42
Das Problem ist, dass es mit deinem Ansatz in sed(1) keine Moeglichkeit gibt, ein zehntes Feld zu addressieren.
Ja, zumindest nicht direkt, das weiß ich doch. "One of the main problems is selecting the correct tool for the job." "One of the fundamental rules of programming is strength reduction." Die Spezifikation war 9 Felder, also habe ich meine sed-Lösung gewählt. Wäre sie 10 Felder gewesen, hätte ich eine andere Lösung gewählt.

Ich habe also Glück, weil ich das zur Spezifikation passende Tool gewählt habe? Wenn das so wäre, dann müsste ich meinen Beruf an den Nagel hängen. :mrgreen:
Das ist also kein Problem von hardgecodeten neun Feldern, sondern von einem Verfahren, das nur bis neun Felder moeglich ist. Darum hast du eben Glueck gehabt, dass es nur neun Felder waren.
Nein. Du argumentierst so, als hätte ich zuerst meine Lösung präsentiert, und hinterher wäre erst herausgekommen, daß es sich um 9 Spalten handelt, und daher hätte ich Glück gehabt, daß meine Lösung zum Problem passt. Dem ist aber nicht so. Meine Lösung passt deshalb zum Problem, weil ich sie so gebriegelt habe.
(Und meine Bemerkung ist wirklich mit diesem Augenzwinkern zu verstehen.)
Bei mir sind eigentlich meine ganzen Beiträge mit einem Augenzwinkern zu verstehen.
Zuletzt geändert von owl102 am 24.08.2017 08:40:54, insgesamt 1-mal geändert.

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Shellscript String zerschneiden

Beitrag von Meillo » 23.08.2017 22:42:49

@owl102: Ich glaube wir verheddern uns hier in einer Nebensaechlichkeit, die aus einer flapsigen Bemerkung entstanden ist. An sich sind wir, wie es aussieht, sehr aehnlicher Meinung, bloss stehen uns unterschiedliche Betrachtungswinkel und Formulierungen im Weg. Wir koennen die Erbsenzaehlerei weiterfuehren um herauszufinden, an welchen Details wir etwas aus anderem Winkel betrachten, oder es hier einfach gut sein lassen. Ich kann deine letzte Erlaeuterung jedenfalls so stehen lassen.
Use ed once in a while!


Antworten