2017-07-10 3 views
0

Ich bin neu in Bash Scripting Ich habe folgende CSVBash: Parse CSV und bearbeiten Zellenwerte

Eingang

ID Location Way Day DayTime NightTime StandNo 
1 abc  Up mon 6.00  18.00 6 

Erwartete Ausgabe

ID Location Way Day DayTime NightTime StandNo 
1 ABC  UP Mon 6.00  18.00 6 

Ich brauche Lage zu überprüfen und Way und konvertieren sie in UpperCase - ABC, UP Der Tag muss mon - Mon Ich muss dies für die gesamte CSV tun. Ich brauche den Wert zu korrigieren und alle Felder in CSV schreiben oder die aktuelle Zelle bearbeiten und speichern CSV Mein Skript ist als

file = "Myfile.csv" 
while IFS="," read line 
do 
output=`echo $line | cut -d "," -f2` 
echo $output 
for i in $output 
do 
if [ -z $(echo $I | sed -e "s/[a-z]//g") ] 
then 
echo $I | tr "[:lower:]" "[:upper:]" >> ".tempfile.CSV" 
fi 
done 
done <$file 

`1 folgt. Derzeit schreibt dies nur den korrigierten Wert und nicht die gesamte Zeile zusammen mit dem korrigierten Wert. [Unsicher, wie ich Zellenwerte in jeder Zeile durchgehen kann, korrigiere die, die korrigiert werden müssen, und kopiere dann die gesamte Zeile]

Jede Hilfe wäre nützlich.

+0

Bitte [formatieren Sie den Code und Beispiel Eingabe/Ausgabe richtig] (http://meta.stackexchange.com/a/22189/248777). – mklement0

+1

Lernen Sie http://shellcheck.net ** zu verwenden, bevor Sie Ihren Code hier posten ;-). Wenn Sie Shellcheck verwenden, müssen Sie eine richtige "She-Bang" -Zeile als erste Zeile einfügen, normalerweise '#!/Bin/bash'. Viel Glück. – shellter

Antwort

3

Why is using a shell loop to process text considered bad practice?

Siehe Wie Frage linux markiert ist, GNU sed vorausgesetzt, ist vorhanden. Und auch, dass die Eingabe tatsächlich csv ist, nicht Raum/Tab getrennt

$ cat ip.csv 
ID,Location,Way,Day,DayTime,NightTime,StandNo 
1,abc,Up,mon,6.00,18.00,6 
2,xyz,down,TUE,2.32,5.23,4 

$ sed '2,$ {s/[^,]*/\L\u&/4; s/[^,]*/\U&/3; s/[^,]*/\U&/2}' ip.csv 
ID,Location,Way,Day,DayTime,NightTime,StandNo 
1,ABC,UP,Mon,6.00,18.00,6 
2,XYZ,DOWN,Tue,2.32,5.23,4 
  • 2,$ Eingang von 2. Zeile verarbeiten der Datei zu beenden
  • s/[^,]*/\L\u&/4 nur Anfangsbuchstaben 4. Feld kapitalisieren
  • s/[^,]*/\U&/3 kapitalisieren Alle Buchstaben im 3. Feld
  • s/[^,]*/\U&/2 Großbuchstaben im 2. Feld

Wenn die Felder selbst , in doppelten Anführungszeichen und so weiter enthalten können, verwenden perl, python, etc, die csv Module

+0

Hallo Sundeep, Es funktionierte auf Gedit :). Danke. Das Problem war mit MobaXterm Editor. Kann ich wissen, wie \ L \ u zeigt ersten Buchstaben in einem Wort Großbuchstaben? –

+0

'\ L' wird alle Buchstaben klein geschrieben .... '\ u 'wird Großbuchstaben nur einen Buchstaben ... wenn Ihre Eingabe nur Worte wie' mon ',' tue' usw. hat, können Sie überspringen mit '\ L' – Sundeep

+0

Danke, ich habe eine andere Zweifel, wenn du mich willst um einen anderen Thread zu öffnen, werde ich es tun. Ich habe diesen Fall manchmal wo in 100, West Bengal, Up, Thu,,,,. 101,,, Fr, 6.00, 8.00, P3. Ich habe diesen Ausdruck s /, [[: blank:]] *,/,, /. Das funktioniert gut. Aber wenn mehr als 1 Leerzeichen zwischen Begrenzern existiert, funktioniert es nicht –

0

ich Sie gehe davon haben eine headerless CSV-Datei in Eingangs:

$ cat file.csv 
1,abc,Up,mon,6.00,18.00,6 

ich auch gehe davon aus Sie eine CSV-Datei in ausgegeben werden soll.

Wenn alle diese Annahmen richtig sind, dann:

$ awk -F, -v OFS=, '{$2=toupper($2); $4=toupper(substr($4,1,1)) substr($4,2); print}' file.csv 
1,ABC,Up,Mon,6.00,18.00,6 

EDIT. Wenn Sie Ihre Kopfzeile erhalten wollen ...

awk -F, -v OFS=, '{if(NR>1){$2=toupper($2); $4=toupper(substr($4,1,1)) substr($4,2)} print}' file.csv 
ID,Location,Way,Day,DayTime,NightTime,StandNo 
1,ABC,Up,Mon,6.00,18.00,6 
+0

Header muss kopiert werden. Kann ich wissen, wo genau diese Linie eingefügt werden muss? Derzeit gibt es mir einen Fehler, der sagt "Multi-Call-Binär 'Usage: awk [Optionen] [awk_program] [Datei] ... -v var = val set Variable –

+0

@MeghnaSathyanarayan: verstehe nicht, was Sie mit eingefügt bedeuten. Der Befehl Zeile hier oben muss ausgeführt werden (nicht eingefügt). – mauro

+0

Entschuldigung Mauro, ich frame meine Frage neu. Ich habe den Befehl ausgeführt und den Fehler gefunden. Ich dachte wahrscheinlich, dass es irgendwo im vorhandenen Skript hinzugefügt werden sollte. Ich bin ziemlich neu zu bash und ich könnte durcheinander geraten haben –

1

Recall in bash, haben Sie einen Parameter Expansion hat, die alle Zeichen in einer Variablen konvertiert (z.B $line) bis Großbuchstaben. Die Form der Erweiterung ist ${line^^} (beachten Sie die '^^').Zum Lesen und alle Zeichen in den Zeilen nach dem ersten in Großbuchstaben zu umwandeln, können Sie tun:

declare -i c=0 
while read -r line; do 
    if [ "$c" -gt '0' ]; then 
     echo "${line^^}"   ## output line converted to upper 
    else 
     echo "$line" 
    fi 
    ((c++)) 
done < file.txt 

Ausgabe

$ declare -i c=0; while read -r line; do if [ "$c" -gt '0' ]; then \ 
echo "${line^^}"; else echo "$line"; fi; ((c++)); done < file.txt 
ID Location Way Day DayTime NightTime StandNo 
1 ABC  UP MON 6.00  18.00 6