ubuntuusers.de

Verschachtelter Schleifenaufbau mit Bedingung und Abbrechoption und wordcount wc

Status: Ungelöst | Ubuntu-Version: Ubuntu 17.10 (Artful Aardvark)
Antworten |

rafi

Avatar von rafi

Anmeldungsdatum:
7. Februar 2006

Beiträge: 1050

Wohnort: Baden-Baden

Hallo,

mir wurde hier bereits super geholfen und ich bin auch schon mit find gut am start danke. Wieder einmal geht es darum jetzt etwas "sauber" zu machen.

Folgende Situation:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14

while read abschluesse_zeile ; do
count=0  
    while read abrufe_zeile ; do
    count=`expr $count + 1`                   
        positionp=`awk -v a="$abrufe_zeile" -v b="${abschluesse_zeile:2}" 'BEGIN{print index(a,b)}'`
        if [ "$positionp" -gt 0 ]        ;                then
            echo $abschluesse_zeile "wurde bereits abgerufen bei "${abrufe_zeile:9:3}" am "${abrufe_zeile:2:6}
            break
       elif [ $count -eq $anzahl_abrufe ] ;                then        
            echo $abschluesse_zeile "wurde noch nicht abgerufen bei einem Distributor / Provider"
        fi  
    done < ../03_ABRUFE/Abrufe.txt
done < Abschluesse.txt 

zwei verschachtelte Schleifen: Es werden aus der Datei Abschlüsse zeilenweise Dateinamen.pdf ausgelesen. Findet nun eine Übereinstimmung des Dateiname-Strings mit einem aus der ebenso zeilenweise eingelesenen autogenerierten Datei Abrufe.txt statt, so wird dies an die Standartausgabe ausgegeben und die Schleife wird gebrochen und der nächste Abschluss wird eingelesen.

Werden jedoch alle Zeilenstrings der Abrufe.txt mit der Zeile aus Abschluesse.txt verglichen und findet da garkeine Übereinstimmung statt ist die Folgerung daraus, dass es noch keinen Abruf gegeben hat und dies gemacht werden muss.

Wie kann ich das als Bedingung machen, dass nur wenn die Schleife durchgelaufen ist und nicht unterbrochen wurde nur dann echo $abschluesse_zeile "wurde noch bei keinem Distributor/Provider eingereicht." ausgegeben wird.

Ich hatte überlegt zuerst einen Zeilencount zu machen der Abrufdatei und dann am ende wenn die Schleife sooft durchlaufen wurde wie es Zeilen gibt in der Datei und das erfolglos bei der while direktive, dass er erst dann das feststellt.

und da ist mir auch aufgefallen dass wc -l noch den Dateinamen angibt am ende. Bekomme ich wc -l auch als reine Integerwert ohne grosse Stringmanipulation?

Wie krieg ich das als Bedingung hin dass wenn die Schleife durchgelaufen ist ohne erfolg dass es zu break kommt dass erst dann eine Zeile ausgeführt wird?

Der Weg über wordcount lines ist umständlich und nicht elegant, das sagt mir mein Gespür für Ästhetik.

Danke.

PS: Die Frage bei wordcount -list nur einen Integer zu bekommen geht mit wc -l < file.txt anstelle wc -l file.txt

sh4711

Anmeldungsdatum:
13. Februar 2011

Beiträge: 1196

gelöscht

sh4711

Anmeldungsdatum:
13. Februar 2011

Beiträge: 1196

rafi schrieb:

Wie kann ich das als Bedingung machen, dass nur wenn die Schleife durchgelaufen ist und nicht unterbrochen wurde nur dann echo $abschluesse_zeile "wurde noch bei keinem Distributor/Provider eingereicht." ausgegeben wird.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
 while read abschluesse_zeile ; do
 count=0  
 iacount = 0
 ibreak = 0
     while read abrufe_zeile ; do
     count=`expr $count + 1`                   
         positionp=`awk -v a="$abrufe_zeile" -v b="${abschluesse_zeile:2}" 'BEGIN{print index(a,b)}'`
         if [ "$positionp" -gt 0 ]        ;                then
             echo $abschluesse_zeile "wurde bereits abgerufen bei "${abrufe_zeile:9:3}" am "${abrufe_zeile:2:6}
             ibreak = 1
             break
        elif [ $count -eq $anzahl_abrufe ] ;                then        
             iacount = iacount + 1
             sarray[iacount]= $abschluesse_zeile "wurde noch nicht abgerufen bei einem Distributor / Provider\n"
         fi  
     done < ../03_ABRUFE/Abrufe.txt
     if [iacount > 0] && [ibreak != 1] 
        then
        echo "${sarray[@]}"
        unset sarray
     elif [iacount > 0] 
        then
        unset sarray
     fi
    
 done < Abschluesse.txt 

 

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13219

Wenn ich das richtig sehe, kannst Du Deine komplette Auswertung viel einfacher machen:

1
fgrep -f ../03_ABRUFE/Abrufe.txt Abschluesse.txt

Aber Du willst ja für jede Zeile eine Ausgabe machen. Dann würde ich das mit awk so bauen, dass erst einmal ../03_ABRUFE/Abrufe.txt eingelesen und gespeichert wird und dann jede Zeile der zweiten Datei gegen die Liste geprüft wird.

Das Muster kannst Du natürlich auch in der bash realisieren, indem Du erst ../03_ABRUFE/Abrufe.txt in ein Array einliest und dann in der inneren Schleife nur über dieses Array iterierst. Sollte effizienter sein.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11269

Wohnort: München

Wie wäre es damit?

1
2
3
4
5
6
7
8
#!/bin/bash
while read -r abschlüsse_zeile ; do
   if abrufe_zeile=$(fgrep "${abschluesse_zeile:2}" ../03_ABRUFE/Abrufe.txt); then
       echo "$abschluesse_zeile wurde bereits abgerufen bei ${abrufe_zeile:9:3} am ${abrufe_zeile:2:6}"
   else
       echo "$abschluesse_zeile wurde noch nicht abgerufen bei einem Distributor / Provider"
   fi
done < Abschluesse.txt 

Wenn die Listen nicht allzu umfangreich sind, kann man den Malus für den wiederholten Dateizugriff möglicherweise verkraften, um die zeitraubenden Substringvergleiche kommt man nicht so einfach herum, ohne mehr über die Datenstruktur zu wissen.

Wenn man da einen gut definierten String pro Zeile in der Abrufe.txt hätte, der sich als Key in einem Hash bzw. Assoziativem Array verwenden ließe, wäre das natürlich eine nette Optimierungsmöglichkeit. Man könnte dafür z.B. statt mit Zeichenpositionen zu arbeiten bestimmte Felder aus der Zeile zusammenfassen.

sh4711

Anmeldungsdatum:
13. Februar 2011

Beiträge: 1196

seahawk1986 schrieb:

Wie wäre es damit?

1
2
3
4
5
6
7
8
#!/bin/bash
while read -r abschlüsse_zeile ; do
   if abrufe_zeile=$(fgrep "${abschluesse_zeile:2}" ../03_ABRUFE/Abrufe.txt); then
       echo "$abschluesse_zeile wurde bereits abgerufen bei ${abrufe_zeile:9:3} am ${abrufe_zeile:2:6}"
   else
       echo "$abschluesse_zeile wurde noch nicht abgerufen bei einem Distributor / Provider"
   fi
done < Abschluesse.txt 

Aufgrund des elif bei rafi bin ich davon ausgegangen, dass hier mehrere Zeilen ausgegeben werden können/sollen. Ist dem nicht so?

rafi

(Themenstarter)
Avatar von rafi

Anmeldungsdatum:
7. Februar 2006

Beiträge: 1050

Wohnort: Baden-Baden

Hallo, vielen Dank.

Im Grunde geht es darum.

Neue Verträge kommen im PDF Format in den Ordner Verträge. Anhand des Dateinamens werden Infos herausgezogen. Was für ein Vertrag, welches Abschlussdatum und welcher Vertriebspartner hat ihn gemacht.

Dann gibt es einen weiteren Ordner Abrufe, dort kommen Verknüpfungen von den Verträgen rein je nachdem bei welchem Portal die Verträge eingereicht wurden, und zwar in Ordner mit Namen des Portals und Datums.

aus diesen Schritten auf Dateiebene arbeite ich dann heraus wieviel Provi die Agentur und wer wann bekommt... Weil der studentische Buchhalter ist nämlich nicht mehr tragbar, der will ne Festanstellung ...

Das skript ließt erst ein welche Portale wieviel Provi für welche Verträge geben, und dann schaut er eben nach ob jeder Abschluss bereits eingereicht wurde und wo und wann (Abruf) dafür wird eine liste erstellt aus allen Dateien im Ordner Verträge und eine Liste von allen Links im jeweiligen Abrufordner und die dann verglichen ...

Ich mag lieber alles mit Ordnern und Skripten händisch haben, wo ich die Verträge direkt über SSH reinpacken kann also wieder so nervige Programme mit GUI und Web wo tausend Leute mit reinpfuschen wollen.

Dann bau ich noch einen Storno Ordner rein, einen Für GE und GA und einen reminder wann man die Kunden wieder kontaktieren muss um weiter mit Ihnen Geld zu machen.

Danke

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11269

Wohnort: München

superhonk schrieb:

Aufgrund des elif bei rafi bin ich davon ausgegangen, dass hier mehrere Zeilen ausgegeben werden können/sollen. Ist dem nicht so?

Damit die Zeile 10 in rafi's Skript aus 8952333 etwas sinnvolles tun kann, müsste die Variable $anzahl_abrufe ja erst mal einen numerischen Wert zugewiesen bekommen - entweder fehlt da etwas vom Skript oder es ist ein Artefakt von früheren Versuchen. Generell ist es ohne Beispieldatensatz, der alle Eventualitäten beinhaltet, etwas schwierig...

rafi

(Themenstarter)
Avatar von rafi

Anmeldungsdatum:
7. Februar 2006

Beiträge: 1050

Wohnort: Baden-Baden

Bestünde denn an diesem Projekt Interesse als OpenSource?

Der baut nachher noch Latex PDFs mit den ganzen Geschäftsfällen und generiert csv-Dateien für die Vertriebspartner (Abrechnung)...

rafi

(Themenstarter)
Avatar von rafi

Anmeldungsdatum:
7. Februar 2006

Beiträge: 1050

Wohnort: Baden-Baden

superhonk schrieb:

Aufgrund des elif bei rafi bin ich davon ausgegangen, dass hier mehrere Zeilen ausgegeben werden können/sollen. Ist dem nicht so?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
symlinks -crs . 
cd 03_ABRUFE
find ./ -name "*.pdf" > Abrufe.txt
anzahl_abrufe=`wc -l < Abrufe.txt`

cd ../04_FORDERUNGEN
rm *

cd ../02_ABSCHLUESSE_PRODUKTION
find ./ -name "*.pdf" > Abschluesse.txt

while read abschluesse_zeile ; do
    count=0
    abschlussdatum=`date '+%y%m%d' -d "${abschluesse_zeile:2:6}"`
    while read abrufe_zeile ; do
    count=`expr $count + 1`                   
        positionp=`awk -v a="$abrufe_zeile" -v b="${abschluesse_zeile:2}" 'BEGIN{print index(a,b)}'`
        if [ "$positionp" -gt 0 ]      ;                then
            abrufdatum=`date '+%y%m%d' -d "${abrufe_zeile:2:6}"`
            distributor=${abrufe_zeile:9:3}
            echo $abschluesse_zeile "wurde am " $abschlussdatum "abgeschlossen und abgerufen bei "$distributor" am "$abrufdatum
            stufe=`find ../09_PARTNER -type f -name "${abschluesse_zeile:19:2}*" -print0 | xargs -0 cat`
            distributordatei=`find ../01_ANBINDUNGEN_RAHMENVERTRAEGE -type f -name "*${abrufe_zeile:9:3}*txt"`
            distributorabruf=`cat $distributordatei | grep -A 5 "${abschluesse_zeile:12:6}"`
            fristabschluss=`awk -v a="$distributorabruf" -v b="Abschluss_bis_" 'BEGIN{print index(a,b)}'`
            fristabruf=`awk -v a="$distributorabruf" -v b="Abruf_bis_" 'BEGIN{print index(a,b)}'`
            vertragname=${distributorabruf:7:fristabschluss-9}
            echo "vertragname" $vertragname
            team_stufe=`awk -v a="$distributorabruf" -v b="$stufe" 'BEGIN{print index(a,b)}'`
            echo "provi stufe:" $stufe
            provision=${distributorabruf:$team_stufe+6:6}
            echo "PROVISION:" $provision
           
            ## AUSZAHLUNG    
            provisionaufteilungposition=`awk -v a="$distributorabruf" -v b="Provision: " 'BEGIN{print index(a,b)}'`
            aufschub=${distributorabruf:$provisionaufteilungposition+15:4}
            provisionaufteilung=${distributorabruf:$provisionaufteilungposition+10:4}
            
                     

            zahltag=`date '+%y%m%d' -d "${abschlussdatum:0:4}${aufschub:2:2} + ${aufschub:0:2} month"`
            provi1=`echo $provision"*"$provisionaufteilung | bc`
 
               ## GELD SOFORT ODER EIN MONAT SPÄTER
            if [ "${abschluesse_zeile:6:2}" -lt "${distributorabruf:$fristabschluss+13:2}" ] && [ "${abrufe_zeile:6:2}" -lt "${distributorabruf:$fristabruf+9:2}" ]       ;                then
                :
            else
                zahltag=`date '+%y%m%d' -d "$zahltag + 1 month"`
            fi
            echo "Am" $zahltag "sind" $provi1 "Euro Provision1 aus einem" $vertragname" von" $distributor "fällig. :-)"   
            echo "Am" $zahltag "sind" $provi1 "Euro Provision1 aus einem" $vertragname "fällig. :-)"   >> ../04_FORDERUNGEN/"$zahltag$distributor"
           
               ##MIT RÜCKSTORNOEINBEHALT         
            if [  "$provisionaufteilung" != "1.00" ];                then

                provisionaufteilung2=${distributorabruf:$provisionaufteilungposition+21:4}
                provi2=`echo $provision"*"$provisionaufteilung2 | bc`
                aufschub2=${distributorabruf:$provisionaufteilungposition+26:4}
                zahltag2=`date '+%y%m%d' -d "${abschlussdatum:0:4}${aufschub2:2:2} + ${aufschub2:0:2} month"`
                if [ "${abschluesse_zeile:6:2}" -lt "${distributorabruf:$fristabschluss+13:2}" ] && [ "${abrufe_zeile:6:2}" -lt "${distributorabruf:$fristabruf+9:2}" ]       ;                then
                    :
                else
                    zahltag2=`date '+%y%m%d' -d "$zahltag2 + 1 month"`
                    
                fi  
            echo "Am" $zahltag2 "sind" $provi2 "Euro Provision2 aus einem" $vertragname" von" $distributor "fällig. :-)"   
            echo "Am" $zahltag2 "sind" $provi2 "Euro Provision2 aus einem" $vertragname "fällig. :-)"   >> ../04_FORDERUNGEN/"$zahltag2$distributor"          
            fi
            break
       elif [ $count -eq $anzahl_abrufe ] ;                then        
            echo $abschluesse_zeile "wurde noch nicht abgerufen bei einem Distributor / Provider"
        fi  
    done < ../03_ABRUFE/Abrufe.txt
done < Abschluesse.txt 

ich werde heute Nacht versuchen das egrep zu integrieren...

es muss auch noch die Boni und OnTop ZielVereinbarung mitrein, sofern die aufs deutsche Konto soll.

Antworten |