• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

CSV Datei aufsplitten in mehrere Files

A

Anonymous

Gast
Flash schrieb:
Wenn ich das hier ausführe: foo@bar:~/Downloads$ grep Transaktionen *.txt > foobar.txt

dann sieht das resultat in foobar.txt so aus:
Code:
report (10).txt:Transaktionen: 30								
report (11).txt:Transaktionen: 66
report (12).txt:Transaktionen: 27
report (13).txt:Transaktionen: 42
.....
report (9).txt:Transaktionen: 29
report.txt:Transaktionen: 18

die Dateinamen werden mit ausgegeben. Ich möchte da gern einen anderen Trenner hinter dem Dateinamen haben. Statt : halt , oder gar kein Dateiname.
Dann wie folgt zu lösen
framp schrieb:
Hänge einfach einen Pipe zu sed dran wo Du das erste : durch ein , ersetzt ;)
Code:
| sed 's/:/,/'
ist der falsche Weg, Immer so einfach wie nur möglich, und nicht im ersten Schritt gleich irgendwelche aufkommenden Probleme gleich mit zusätzlichen Code beseitigen, sonder immer zuerst mal in die Manpage schauen ob es da nicht vielleicht Optionen gibt die einem nicht so geläufig sind, aber die Probleme schon vorn vorne herein beseitigen.
grep -h unterdrückt die Ausgabe von Dateinamen. -H ( wie framp schon oben bemerkt) gibt sie expilizied mit aus, auch dann wenn nur eine einzige Datei durchsucht wird.
Flash schrieb:
die CSV Zeilen sehen ungefähr so aus
Code:
"asdasd_asdasda_dasdas","TYP-A","000-123213-4121231","fhjkasdasdsa asdas asdasda","12","35678","fhjkasdasdsa asdas asdasda"
"avgask_fsaasda_dasdas","TYP-A","000-123213-4121231","fhjkasdasdsa asdas asdasda","13","35678","fhjkasdasdsa asdas asdasda"
"asdasd_asdasda_dasdas","TYP-B","000-123213-4121231","fhjkasdasdsa asdas asdasda","2","35678","fhjkasdasdsa asdas asdasda"
"asdasd_asdasda_dasdas","TYP-A","000-123213-4121231","fhjkasdasdsa asdas asdasda","222","35678","fhjkasdasdsa asdas asdasda"

Ich möchte nun gern folgendes machen: Wenn in der Spalte mit TYP- ein "TYP-B" steht, dann soll die Zahl 3 Spalten weiter hinten negiert werden. Also im Fall oben aus der 2 soll eine -2 werden.
Ich hatte mir überlegt, man könnte ja einen RegEx Matcher bauen der ab TYP-B sucht und durch ein geschicktes Muster genau das erreicht. Nur ist mein RegEx doch zu schwach.
Mal abgesehen, was du 3 Spalten weiter als Zahl bezeichnest steht in Hochkommas eingeschlossen und ist folglich Text, aber wir wollen mal nicht kleinlich sein.

sicherlich kann man da einen RegEx bauen, der das erledigt, zB.
Code:
sed  's/\(TYP-B\",[^,]\+,[^,]\+,\"\)/\1-/'
bringt dich aber nicht weiter wenn du ihn nicht wirklich verstehst, wie er funktioniert.
Möglichkeit B wäre in der Bash die Zeile in Spalten zu zerlegen, dann könntest du bequem die Spalte 2 nach "TYP-A/B" absuchen und dann die Spalte 5 bequem ändern. und entsprechend dem Ergebnis von Test auf Spalte 2 das Ganze dann in die jeweilige Datei schreiben. Kein Problem sowas in Bash zu schreiben, aber kann dir nicht versprechen das dann noch jeder annähernd verstehst, was dort passiert.

Code:
#!/bin/bash
FILEA="FILE_TYP_A.txt"
FILEB="FILE_TYP_B.txt"
echo "Begrüßungstext für Type-A" > $FILEA
echo "Begrüßungstext für Type-B" > $FILEB

OLD_IFS=$IFS
IFS=","
while read A B C D E F G 
do 
      if [ "${B}" == \""TYP-B\"" ] 
      then   
         E=${E/\"/\"-}
         echo $A,$B,$C,$D,$E,$F,$G >> $FILEB
      else 
         if [ -n "$B" ] 
         then  
            echo $A,$B,$C,$D,$E,$F,$G >> $FILEA 
         fi
      fi
 done < <(cat $*) 
IFS=$OLD_IFS
Ausführungsrechte auf Script geben, Aufruf : ./script Datei1.csv Datei2.csv .............

Wobei wir wieder bei meinem Satz von oben sind, Immer so einfach wie nur möglich, also wenn möglich ein Programm/Tool verwenden das für die Aufgabe geeignet ist
und möglichst intern schon genau so arbeitet wie man es braucht, das spart nen Haufen Zeit bei der Scripterstellung und beim Testen.
awk bietet sich hier natürlich an
Code:
#!/usr/bin/awk -f
 
 BEGIN {
       FS=","
       OFS=","
       FILE1="TYP_A.txt"
       FILE2="TYP_B.txt"
       print "HALLO Begrüßungstest für TYP_A" > FILE1 
       print "HALLO Begrüßungstest für TYP_B" > FILE2 
 }
 $2 ~ /TYP-A/ {
       print ( $0 ) >> FILE1 
 }
 $2 ~ /TYP-B/ {
       sub("\"","\"-",$5)                                    # im 5. Feld wird  das erste " durch "-  ausgewechselt
       print( $0 ) >>  FILE2
 }
Ausführungsrechte auf Script geben, Aufruf : ./script Datei*.csv

Ist auch nicht schwieriger zu verstehen und die gesamte Dokumentation für awk umfasst nur die Halbe Größe der Manpages von bash und bashutils die man eventuell durchsuchen müßte um das bashscript zu verstehen.

robi
 

abgdf

Guru
robi schrieb:
sicherlich kann man da einen RegEx bauen, der das erledigt, zB.
Code:
sed -n 's/\(TYP-B\",[^,]\+,[^,]\+,\"\)/\1-/p'
bringt dich aber nicht weiter wenn du ihn nicht wirklich verstehst, wie er funktioniert.
Da krieg' ich die Zahnstocherkrankheit (sed ////\\\\\\ - Zahnstocher). :mrgreen:
robi schrieb:
awk bietet sich hier natürlich an
...
Ist auch nicht schwieriger zu verstehen und die gesamte Dokumentation für awk umfasst nur die Halbe Größe der Manpages von bash und bashutils die man eventuell durchsuchen müßte um das bashscript zu verstehen.
Ja, ja. Seit zig Jahren laufen diese Themen immer in der gleichen Weise, und noch nie hat jemand deswegen awk gelernt. (Ok, Perl wohl auch nicht).
Aber man kann wirklich nicht sagen, daß awk leicht zu verstehen sei. Es geht eine Datei eben zeilenweise durch (wie "perl -p -i ..."). In der Perl-Doku ("perldoc perlrun") steht zu dem Mechanismus:
causes Perl to assume the following loop around your program, which makes it iterate over filename arguments somewhat like ...
und das ist eben überhaupt nicht leicht zu verstehen, da verliert man ganz leicht die Kontrolle. Da ist es mir schon wesentlich lieber, wenn man gleich etwas Richtiges lernt, und den "Loop around your program" selbst schreibt, bzw. überhaupt schreiben kann (awk läßt das ja gar nicht zu). Also, ich vermeide diese vermeintlich kurzen Einzeiler a la "perl -p -i" oder eben "awk ...", wenn ich kann. Da schreib' ich mir lieber mein Skript ganz selbst.
In Perl ist das auch viel leichter als in bash. Und zwar, weil Dateinamen da so funktionieren, wie man es erwartet: Leerzeichen, Sonderzeichen und Umlaute stellen keine Gefahr dar. Und Variablen verschwinden auch nicht plötzlich unbemerkt in Subshells.

Aber bitte, jeder wie er mag. Ich denke nur, wenn der Threadersteller nicht noch eine ganze Menge lernt (was auch immer, am besten das Richtige), wird er die Ziele, die er mit seiner Datenverarbeitung hat, nicht erreichen können.
 
Oben