staging.inyokaproject.org

Stringbearbeitung

Status: Gelöst | Ubuntu-Version: Ubuntu 18.04 (Bionic Beaver)
Antworten |

black_tencate

Avatar von black_tencate

Anmeldungsdatum:
27. März 2007

Beiträge: 11349

Hej,

mit

pdfgrep -rh  --include "*.pdf" <Suchstring>

finde ich aus einer Menge von pdf-Dateien die Zeilen mit dem Suchstring. So weit so gut. Aus jeder Zeile möchte ich aber nur ganz bestimmte Teile auflisten:

02.05.2018 xxxxxxx <Suchstring> xxxxxx xxxxxxxx xxxxx -yyyyyyy

und zwar die markierten, im letzen Fall "-" auch noch die folgenden Ziffern (unterschiedlich viele). Alles was hier mit "x" gezeigt ist (unterschiedlich lang) soll weg, und die Leerzeichen auch.

Mit LOCalc klappt das eher eher solala wegen der unterschiedlich vielen Leerzeichen zwischen den erwünschten Anteilen.

Leider weiß ich überhaupt kein Bescheid

Gruß black tencate

TausB

Avatar von TausB

Anmeldungsdatum:
26. November 2009

Beiträge: 1570

Können das "-" bzw. "<" oder ">" mehrmals - also auch innerhalb der "xxx" - vorkommen? Falls nicht:

In LO-Calc (Der gesamte String steht in A1):

  • 02.05.2018 =LINKS(A1;10)

  • Suchstring =TEIL(A1;FINDEN("<";A1)+1;LÄNGE(A1)-FINDEN("<";A1)-FINDEN(">";A1)-1)

  • -yyyyyyy =RECHTS(A1;LÄNGE(A1)-FINDEN("-";A1)+1)

Falls die drei Teilergebnisse in einer Zelle stehen sollen, sind die einzelnen Formeln mit "&" zu verbinden.

black_tencate

(Themenstarter)
Avatar von black_tencate

Anmeldungsdatum:
27. März 2007

Beiträge: 11349

Hej TausB,

TausB schrieb:

Können das "-" bzw. "<" oder ">" mehrmals - also auch innerhalb der "xxx" - vorkommen? Falls nicht:

ich habe wohl mit <string> auf die falsch Fährte geführt, hätte string (ohne "<", ">") sein sollen. Durch geeignetes Haken-setzen unter "Trennoptionen" habe ich dann eher zufällig eine Variante, bei welcher im Ergebnis nur wenige Spalten "verrutscht" waren, bekommen.

> Jedoch, mir schwebt halt immer noch eine Lösung im Terminal vor. <

In LO-Calc (Der gesamte String steht in A1):

  • 02.05.2018 =LINKS(A1;10)

  • Suchstring =TEIL(A1;FINDEN("<";A1)+1;LÄNGE(A1)-FINDEN("<";A1)-FINDEN(">";A1)-1)

  • -yyyyyyy =RECHTS(A1;LÄNGE(A1)-FINDEN("-";A1)+1)

*gins*, das erinnert mich stark meine Excelzeit, da habe ich mal m bzw n Elemente aus zwei Spalten zu einer zusammengefügt

Spalte E
WENN(WENN(WENN(REST(ZEILE(A1);m+n)=0;REST(ZEILE(A1)-1;m+n)+1;REST(ZEILE(A1);m+n))=WENN(REST(ZEILE(A1);n)=0;REST(ZEILE(A1)-1;n)+1;REST(ZEILE(A1);n));WENN(REST(ZEILE(A1);m+n)=0;REST(ZEILE(A1)-1;m+n)+1;REST(ZEILE(A1);m+n));WENN(REST(ZEILE(A1);m+n)=0;REST(ZEILE(A1)-1;m+n)+1;REST(ZEILE(A1);m+n))-n)<=0;WENN(WENN(REST(ZEILE(A1);m+n)=0;REST(ZEILE(A1)-1;m+n)+1;REST(ZEILE(A1);m+n))=WENN(REST(ZEILE(A1);n)=0;REST(ZEILE(A1)-1;n)+1;REST(ZEILE(A1);n));WENN(REST(ZEILE(A1);m+n)=0;REST(ZEILE(A1)-1;m+n)+1;REST(ZEILE(A1);m+n));WENN(REST(ZEILE(A1);m+n)=0;REST(ZEILE(A1)-1;m+n)+1;REST(ZEILE(A1);m+n))-n)+n;WENN(WENN(REST(ZEILE(A1);m+n)=0;REST(ZEILE(A1)-1;m+n)+1;REST(ZEILE(A1);m+n))=WENN(REST(ZEILE(A1);n)=0;REST(ZEILE(A1)-1;n)+1;REST(ZEILE(A1);n));WENN(REST(ZEILE(A1);m+n)=0;REST(ZEILE(A1)-1;m+n)+1;REST(ZEILE(A1);m+n));WENN(REST(ZEILE(A1);m+n)=0;REST(ZEILE(A1)-1;m+n)+1;REST(ZEILE(A1);m+n))-n))
Spalte F
WENN(m>=2;WENN(WENN(REST(ZEILE(A1);m+n)=0;REST(ZEILE(A1)-1;m+n);REST(ZEILE(A1);m+n))>n;x+y;x);WENN(n=1;WENN(REST(ZEILE(A1);m+n)=1;x;x+y);WENN(n=2;WENN(UND(n=2;m=1;GANZZAHL((ZEILE(A1))/(n+m))<>GANZZAHL((ZEILE(A1)-1)/(n+m)));x+y;x);WENN(GANZZAHL((ZEILE(A1))/(n+m))<>GANZZAHL((ZEILE(A1)-1)/(n+m));x+y;x))))))
spalte G
INDIREKT(ADRESSE(E1+GANZZAHL((ZEILE(A1)-1)/(n+m))*WENN(WENN(REST(ZEILE(A1);m+n)=0;REST(ZEILE(A1)-1;m+n)+1;REST(ZEILE(A1);m+n))>n;m;n);F1;;;"tabelle2"))

das hatte (ich glaube das war s.Z. seahawk1986) mir dann sehr elegant "auseinander genommen"

Gruß blacktencate

ChickenLipsRfun2eat Team-Icon

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12067

Hallo!

Kannst du nicht pdfgrep mit -o/--only-matching aufrufen? Oder widerspricht das den tatsächlichen Zeilen? Das gibt ja wie in grep dann nur den gewünschten Teil aus. Alternativ durch awk jagen, nur $1, $3 und $NF ausgeben.
pdfgrep -rh --include "*.pdf" <Suchstring> | awk -F' ' '{ print $1 $2 $NF }'

black_tencate

(Themenstarter)
Avatar von black_tencate

Anmeldungsdatum:
27. März 2007

Beiträge: 11349

Hej ChickenLipsRfun2eat,

ChickenLipsRfun2eat schrieb:

Hallo!

Kannst du nicht pdfgrep mit -o/--only-matching aufrufen? Oder widerspricht das den tatsächlichen Zeilen? Das gibt ja wie in grep dann nur den gewünschten Teil aus. Alternativ durch awk jagen, nur $1, $3 und $NF ausgeben.
pdfgrep -rh --include "*.pdf" <Suchstring> | awk -F' ' '{ print $1 $2 $NF }'

leider paßt das auch nicht besser, weil sich die Zeilen unterscheiden

01.04.2019     xxxxxxxx /     suchstring xx xx xx                     xx           -25,00
 02.01.2015       xxxxxxxxxxxxxxxxxxxx           suchstring xx xx       xx                              -25,00

Gruß black tencate

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Verstehe ich das richtig, dass am Zeilenanfang immer ein Datum im Format dd.mm.YYYY steht und am Ende der Zeile ein negativer Dezimalbetrag? Dann könnte man das so machen:

$ sed -nE 's/[[:space:]]*([0-9][0-9]\.[0-9][0-9]\.[0-9][0-9][0-9][0-9]).*(suchstring).*(-[0-9]{1,},[0-9][0-9])/\1\t\2\t\3/p' << EOF
01.04.2019     xxxxxxxx /     suchstring xx xx xx                     xx           -25,00
 02.01.2015       xxxxxxxxxxxxxxxxxxxx           suchstring xx xx       xx                              -25,00
EOF
01.04.2019      suchstring      -25,00
02.01.2015      suchstring      -25,00 

black_tencate

(Themenstarter)
Avatar von black_tencate

Anmeldungsdatum:
27. März 2007

Beiträge: 11349

Hej seahawk1986,

seahawk1986 schrieb:

Verstehe ich das richtig

im Prinzip ja, ich glaube aber, es wäre besser, ich verstünde mehr als nur, daß mit

  • a. ([0-9][0-9]\.[0-9][0-9]\.[0-9][0-9][0-9][0-9]) das Datum, und entsprechend mit

  • b. (-[0-9]{1,},[0-9][0-9]) die negative Zahl mit 2 Nachkommastellen gemeint ist. Ferner reime ich mir zusammen

  • c. s/[[:space:]] (?) laß die spaces aus (?) und

  • d. \1\t\2\t\3/p print a 2=suchstring c (was ist t ?)

Und dann die ganz spannende Frage: Wie/was packe ich ins Terminal

  1. sed -nE 's/[[:space:]]*([0-9][0-9]\.[0-9][0-9]\.[0-9][0-9][0-9][0-9]).*(suchstring).*(-[0-9]\.[0-9][0-9][0-9],[0-9][0-9])/\1\t\2\t\3/p' << EOF das führende "$" gehört da wohl nicht hin?

  2. daran den print von pdfgrep -rh --include "*.pdf" <suchstring> anhängen

Du siehst, ich habe keinen blassen Schimmer, und wenn ich so bei man sed blättere, kommen mir leider auch nicht so die rechten Erleuchtungen.

Gruß black tencate

Und 'ne neue Tastatur für diesen refurbished T520 muß wohl auch mal her (shift rechts und space nur noch mit Gewalt!).

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Das führende $ symbolisiert einen Shell-Prompt, bei dem man einen Befehl eingibt (damit man das besser von Zeilen mit Ausgabe unterscheiden kann). Die Konstruktion << EOF bis zum nächten EOF ist ein Heredoc, damit kann man einem Programm Eingaben aus einer ad-hoc Datei (die man als Teil des Befehls eingibt) unterschieben.

Du kannst die Ausgabe von pdfgrep per Pipe (vgl. Shell/Umleitungen) an den sed-Befehl weiterleiten:

1
pdfgrep -rh --include "*.pdf" 'suchstring' | sed -nE 's/[[:space:]]*([0-9][0-9]\.[0-9][0-9]\.[0-9][0-9][0-9][0-9]).*(suchstring).*(-[0-9]{1,},[0-9][0-9])/\1\t\2\t\3/p'

Zu den Fragen bei der sed-Syntax:

  • [[:space:]]* matcht 0 oder mehr ASCII-Whitespace-Zeichen

  • \t ist ein Tab - wenn dir ein anderes Trennzeichen lieber ist, kannst du das natürlich stattdessen verwenden

black_tencate

(Themenstarter)
Avatar von black_tencate

Anmeldungsdatum:
27. März 2007

Beiträge: 11349

Hej seahawk1986,

seahawk1986 schrieb:

Das führende $ symbolisiert einen Shell-Prompt, bei dem man einen Befehl eingibt (damit man das besser von Zeilen mit Ausgabe unterscheiden kann). Die Konstruktion << EOF bis zum nächten EOF ist ein Heredoc, damit kann man einem Programm Eingaben aus einer ad-hoc Datei (die man als Teil des Befehls eingibt) unterschieben.

Du kannst die Ausgabe von pdfgrep per Pipe (vgl. Shell/Umleitungen) an den sed-Befehl weiterleiten:

1
pdfgrep -rh --include "*.pdf" 'suchstring' | sed -nE 's/[[:space:]]*([0-9][0-9]\.[0-9][0-9]\.[0-9][0-9][0-9][0-9]).*(suchstring).*(-[0-9]{1,},[0-9][0-9])/\1\t\2\t\3/p'

paßt, danke, eine Frage hätte ich noch (-[0-9]{1,} "[0-9]" ok, aber "{1,}" ❓ Also z.B. nicht nur -25,00 sondern auch 1.177,25

Zu den Fragen bei der sed-Syntax:

gibt 's da was verständlichereches als man

Gruß black tencate

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

black_tencate schrieb:

eine Frage hätte ich noch (-[0-9]{1,} "[0-9]" ok, aber "{1,}" ❓

[0-9]{1,} sagt, dass es mindestens eine Zahl geben muss, damit er darauf matcht - man könnte das auch als [0-9]+ schreiben.

gibt 's da was verständlichereches als man

Es gibt das Handbuch für GNU sed: https://www.gnu.org/software/sed/manual/sed.html

Also z.B. nicht nur -25,00 sondern auch 1.177,25

Ich würde da eine Sprache bevorzugen, die mehr Struktur reinbringt, um ein Datum oder einen Betrag zu validieren - z.B. mit Python3:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env python3
import fileinput
import datetime
import locale
import sys

locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')

for line in fileinput.input(files=('-',)):
    for s in sys.argv[1:]:
        if s in line:
            day, *_, amount = line.split()
            try:
                ts = datetime.datetime.strptime(day, "%d.%m.%Y")
                value = locale.atof(amount)
            except ValueError:
                continue
            else:
                print(ts.date(), s, value, sep='\t') # Daten, die sich leichter in der Shell verarbeiten lassen
                # print(day, s, amount, sep='\t') # wenn man die Daten unverändert beibehalten will

Das kann man dann als ausführbare Datei nutzen:

pdfgrep -rh --include "*.pdf" 'suchstring' | ./filter_lines.py 'suchstring' 

Durch die Formatumwandlung (ISO-Datum, Punkt als Dezimaltrennzeichen und Verzicht auf Tausender-Trennzeichen) kann man dann auch leichter in der Shell weiterrechnen.

black_tencate

(Themenstarter)
Avatar von black_tencate

Anmeldungsdatum:
27. März 2007

Beiträge: 11349

Hej seahawk1986,

werde mal ein bißchen "studieren" was sed angeht. Auch den Vorschlag mit Python probiere ich noch aus, danke dafür.

Ich setze derweil hier auf 'gelöst'

Gruß black tencate

EDIT.: gerade getestet, und zu 99% für gut befunden. Kleiner Haken: pdfgrep scheint sich nicht für den Schalter -i "zu interessieren", ein Suchstring "Abcde" liefert andere Ergebnisse als "ABCDE", trotz "-i"

Antworten |