rurotil
Anmeldungsdatum: 7. April 2009
Beiträge: 96
|
Hallo Zusammen, ich hätte zu awk oder sed ein paar Fragen. 1. ist es möglich mit awk eine Formel einzugeben
z.B.
=WENN(I2=0;E2*1,2;I2) und Ausgabe in Tabelle AY 2. Kann ich mit awk oder sed Spalten umbenennen?
ProductId;Kundennummer;Manufacturer;Price_B2B;CategoryPath z.B. ProdctID in ID?? 3. Ich habe ein paar Zeilen in einer 2 CSV Datei, wie kann ich die am Ende einfügen? 4. Wie kann ich es darstellen, dass immer wenn sich die Kundennummer ändert, dass beim ersten mal in ProductID das Feld NEU reingeschrieben wird und danach nur PARENT? ProductId;Kundennummer;Manufacturer;Price_B2B;CategoryPath
NEU,5000,Test,20,Test
PARENT,5000,Test,20,Test
PARENT,5000,Test,20,Test
PARENT,5000,Test,20,Test
NEU,4000,Test,20,Test
PARENT,4000,Test,20,Test
|
Doc_Symbiosis
Anmeldungsdatum: 11. Oktober 2006
Beiträge: 4351
Wohnort: Göttingen
|
Zu 1.: Kannst Du mal in Worten sagen, was Du machen willst. Ich verstehe id eBezeichnungen in der Formel nicht. Zu 2.:
sed -ie '1s/ProductID/ID/' test.csv Zu 3.:
cat zweite.csv >> erste.csv Zu 4.: Dafür müsstest Du mal deinen Code zeigen.
|
rurotil
(Themenstarter)
Anmeldungsdatum: 7. April 2009
Beiträge: 96
|
Vielen Dank für die schnelle Antwort. zu 1 Wenn in Spalte I2 kein Preis ist, dann E2 * 1,2 ansonsten wenn I2 einen Preis hat, dann den Preis und alles in Spalte AY Speichern. =WENN(I2=0;E2*1,2;I2) und Ausgabe in Tabelle AY zu 4
Da habe ich keinen CODE. Die Spalte ProductId ist Standardmäßig leer. Diese soll aber gefüllt werden mit NEU oder PARENT.
D.h. immer wenn sich in Spalte 2 die Kundennummer ändert, soll in Spalte 1 bei ProductID wieder das Wort "NEU" geschrieben werden. Ich hatte noch vergessen, ich müsste die Tabelle vorher nach Spalte 2 Sortieren. Geht das auch? ProductId;Kundennummer;Manufacturer;Price_B2B;CategoryPath
NEU,5000,Test,20,Test
PARENT,5000,Test,20,Test
PARENT,5000,Test,20,Test
PARENT,5000,Test,20,Test
NEU,4000,Test,20,Test
PARENT,4000,Test,20,Test
|
shiro
Anmeldungsdatum: 20. Juli 2020
Beiträge: 811
|
Hallo rurotil, was du an Informationen gibst, ist für mich leider nicht ganz verständlich. Ich vermute, du hast eine Excel/localc Tabelle weil du von I2 und E2 Zellen schreibst. Die csv Daten (mal mit ";", mal mit "," als Feldtrennzeichen) passen aber nicht zu deiner "=WENN()" Formel. Aber mal der Reihe nach:
Eine csv Datei enthält Werte und/oder Text und keine Formeln. Die Sortier-Regeln (1. Spalte mal "NEU" und mal "PARENT") werden in Excel/local anders gelöst als in awk. Mit "sed" kannst du nicht rechnen, daher wird deine "Lösung" eher auf "awk" aufsetzen.
Das Rechnen deiner "=WENN()" Formel kannst du in awk wie folgt lösen:
echo -e "0;20\n10;20" | awk -F";" '{print $1 FS $2 FS ($1==0?$2*1.2:$1)}'
0;20;24
10;20;10
Die erste Spalte ($1) entspräche deiner "I2" Zelle, die 2. Spalte ($2) entspräche deiner "E2" Zelle. Bei der Ausgabe wird als 2. Spalte der berechnete Wert ausgegeben. Es wäre sehr hilfreich, wenn du mal deine konkreten Daten (anonymisiert) in ein paar Zeilen bereit stellen könntest, damit man verstehen kann, was du in den benannten Spalte (1. Zeile) überhaupt meinst.
|
rurotil
(Themenstarter)
Anmeldungsdatum: 7. April 2009
Beiträge: 96
|
Hallo Shiro Sorry für das Missverständnis. Ja ich habe eine Excel / CSV Tabelle. ID Reference EAN Hersteller Price_B2B Price_B2B_Angebot Price_B2B_Prozent Price_B2B_Discount Price_B2C_ohneSteuer Price_B2C_mitSteuer STEUERSATZ LAND Währung PREIS
111 111 TEST 1,5 1,5 0 0 2 19 DE EUR 1,8
222 222 TEST 8,29 5,5 0 0 10,08 12 19 DE EUR 10,8
333 333 TEST 1,45 1,45 0 0 1,69 2,01 19 DE EUR 1,69 bzw. CSV Datei ID;Reference;EAN;Hersteller;Price_B2B;Price_B2B_Angebot;Price_B2B_Prozent;Price_B2B_Discount;Price_B2C_ohneSteuer;Price_B2C_mitSteuer;STEUERSATZ;LAND;Währung;PREIS
111;111;;TEST;1,5;1,5;0;0;;2;19;DE;EUR;1,8
222;222;;TEST;8,29;5,5;0;0;10,08;12;19;DE;EUR;10,8
333;333;;TEST;1,45;1,45;0;0;1,69;2,01;19;DE;EUR;1,69 Und in der Tabelle ist jetzt z.B. bei I2 kein Preis. Dann soll der Preis von E2 * 1,12 berechnet werden und in Feld N2 geschrieben werden.
Ich möchte das über BASH lösen und nicht immer über Excel machen.
Das dies mit awk oder sed nichts zu tun hat ist mir auch klar, das hatte sich gerade nur so aus der Situation ergeben. Kann ich aber mit awk die Zeilen in einer Tabelle sortieren? Natürlich dann nicht nur eine Spalte, sondern die ganze Tabelle.
|
shiro
Anmeldungsdatum: 20. Juli 2020
Beiträge: 811
|
Kann ich aber mit awk die Zeilen in einer Tabelle sortieren? Natürlich dann nicht nur eine Spalte, sondern die ganze Tabelle.
Ja, kann man (siehe asort, asorti über Arrays). Muss man aber nicht, da dies auch ein "sort" vor dem pipen in awk geht. Hier mal einen Vorschlag für deine Daten, denen ich noch einen weiteren Satensatz (wegen "NEU"/"PARENT") eingefügt habe.
echo "ID;Reference;EAN;Hersteller;Price_B2B;Price_B2B_Angebot;Price_B2B_Prozent;Price_B2B_Discount;Price_B2C_ohneSteuer;Price_B2C_mitSteuer;STEUERSATZ;LAND;Währung;PREIS
111;111;;TEST;1,5;1,5;0;0;;2;19;DE;EUR;1,8
111;111;;TEST;3,14;2,5;0;0;;2;19;DE;EUR;
222;222;;TEST;8,29;5,5;0;0;10,08;12;19;DE;EUR;10,8
333;333;;TEST;1,45;1,45;0;0;1,69;2,01;19;DE;EUR;1,69" |
sed 's/,/./g' |
awk -F";" 'BEGIN{
oldRef=""
OFS="\t"
}{
if(NR==1){
$1=$1
}else{
if($2 != oldRef){$1="NEU";oldRef=$2}else{$1="PARENT"}
#E->5; I->9; N->14
$14= $9+0 == 0 ? $5*1.2 : $9
}
print $0
}' | column -t -o "|" -s $'\t'
erzeugt die Ausgabe
ID |Reference|EAN|Hersteller|Price_B2B|Price_B2B_Angebot|Price_B2B_Prozent|Price_B2B_Discount|Price_B2C_ohneSteuer|Price_B2C_mitSteuer|STEUERSATZ|LAND|Währung|PREIS
NEU |111 | |TEST |1.5 |1.5 |0 |0 | |2 |19 |DE |EUR |1.8
PARENT|111 | |TEST |3.14 |2.5 |0 |0 | |2 |19 |DE |EUR |3.768
NEU |222 | |TEST |8.29 |5.5 |0 |0 |10.08 |12 |19 |DE |EUR |10.08
NEU |333 | |TEST |1.45 |1.45 |0 |0 |1.69 |2.01 |19 |DE |EUR |1.69 Zum Script:
Der CSV Datenstrom wird durch "sed" geschickt, damit Komma-separierte Dezimalzahlen in Punkt-separierte gewandelt werden. Dies ist die englische Darstellung einer reellen Zahl. Für den "awk" Befehl wird das Spaltentrennzeichen (-F) auf ";" gesetzt. Der BEGIN Block wird ausgeführt, bevor die Daten aus dem Datenstrom verarbeitet werden. Hierbei wird die Variable "oldRef" auf leer gesetzt, damit später der Wechsel der Werte in der 2. Spalte erkannt werden kann. Die Variable "OFS" ist das Feld-Trennzeichen für die Ausgabe und dies setzte ich auf "TAB". In der ersten Zeile (NR == 1) wird Spalte $1 mit dem Wert von Spalte 1 ersetzt, damit bei der Ausgabe von $0 das Trennzeichen OFS zum tragen kommt. Bei allen weiteren Zeilen wird die erste Spalte mit dem Wert "NEU" / "PARENT" in Abhängigkeit der Spalte $2 gefüllt. Die Spalte "N" ($14) wird berechnet in Abhängigkeit der Spalten "E" ($5) und "I" (9). Nach Ausgabe der modifizierten Eingabezeile $0 wird die Tabelle mit dem Befehl "column" nachbehandelt und als Spaltentrennzeichen das "|" verwendet.
|
rurotil
(Themenstarter)
Anmeldungsdatum: 7. April 2009
Beiträge: 96
|
Hallo Shiro vielen dank für die ganze mühe. Ich fange jetzt an das zu verstehen. Aber wie kann ich das jetzt bei mir anwenden? Hier ist die Tabelle mitten im Script.
Kann ich das Script ohne Tablle nicht in eine Datei schreiben z.B. tabelle.sh sed 's/,/./g' |
awk -F";" 'BEGIN{
oldRef=""
OFS="\t"
}{
if(NR==1){
$1=$1
}else{
if($2 != oldRef){$1="NEU";oldRef=$2}else{$1="PARENT"}
#E->5; I->9; N->14
$14= $9+0 == 0 ? $5*1.2 : $9
}
print $0
}' | column -t -o "|" -s $'\t'
und dann so ausführen ./tabelle.sh test.csv ???
|
shiro
Anmeldungsdatum: 20. Juli 2020
Beiträge: 811
|
So, wie dein "tabelle.sh" Script ausschaut, kannst du es mit der test.csv Datei wie folgt nutzen:
./tabelle.sh <test.csv
# oder
cat test.csv | ./tabelle.sh
Wenn du die Form "./tabelle.sh test.csv" verwenden willst, musst du dies dem Script mitteilen:
# statt
sed 's/,/./g' | ...
# nun
sed 's/,/./g' <$1 | ...
denn test.csv ist in diesem Fall der 1. Parameter für das Script. Durch "<$1" wird der Inhalt der Datei mit dem Namen "$1" zur Verarbeitung durch "sed" geschickt. Die gewählte Darstellung (mit dem echo) habe ich genutzt, um den "NEU"/"PARENT" Fall zu erzeugen und die Eingabedaten im gleichen Code-Block zu listen.
Das awk Script kann man auch wesentlich einfacher ("kürzer") schreiben, ich habe diese eloquente Form gewählt, damit es leichter zu verstehen ist. Die gleiche Aussage trifft auch für das laufende Wechseln des Feld-Trennzeichens (";" → tab → "|") zu. Ich hoffe, damit nicht zu sehr Verwirrung gestiftet zu haben.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12712
|
shiro schrieb:
Wenn du die Form "./tabelle.sh test.csv" verwenden willst, musst du dies dem Script mitteilen:
# statt
sed 's/,/./g' | ...
# nun
sed 's/,/./g' <$1 | ...
Lieber Vorteil: man kann sowohl mehrere Dateinamen übergeben als auch das Skript von Stdin lesen lassen.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12712
|
Übrigens: ich finde das gar nicht gut, dass Du awk spalten willst. So ein tolles Tool - das können wir noch gebrauchen.
|
shiro
Anmeldungsdatum: 20. Juli 2020
Beiträge: 811
|
<OT> ... dass Du awk spalten willst.
Ja, die deutsche Sprache bietet sowohl die Möglichkeit extrem präzise als auch sehr ambivalent zu sein ("Der Gesandte, der geschickt ist").
Der Begriff der Spalte beinhaltet somit sowohl eine Spaltung (Aufteilung in mehrere Säulen/Columns) als auch den Spalt, durch den man etwas Neues erblicken kann.
In diesem Sinn sehe ich hier die Möglichkeit etwas bisher Unbekanntes über den awk Befehl zu entdecken. </OT>
😀 😀 😀
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12712
|
shiro schrieb:
In diesem Sinn sehe ich hier die Möglichkeit etwas bisher Unbekanntes über den awk Befehl zu entdecken.
😀 Guter Punk!
|