2016-07-24 6 views
1

ich bash auf Cygwin bin mit.eine CSV-Datei Neuformatierung, Skript wird von verwirrt ‚%.“‘

Ich habe eine CSV-Datei zu nehmen, die eine Teilmenge von einer viel größeren Gruppe von Einstellungen und shuffle die neuen csv-einstellungen (gleiche schlüssel, verschiedene werte) in die mehr als 1000-linie original, eine neue .json-datei.

Ich habe ein Skript zusammengestellt, um dies zu automatisieren. Der erste Schritt in dem Prozess ist " Bereinigen Sie "die CSV-Datei durch Extrahieren von Zeilen, die mit" Mme "und" SMS "beginnen. Alles andere ist sauber zu übergeben, um die" saubere ". CSV-Datei

Diese Routine ist wie folgt:

# clean up the settings, throwing out mme and sms entries 
cat extract.csv | while read -r LINE; do 
    if [[ $LINE == "mme "* ]] 
     then 
      printf "$LINE\n" >> mme_settings.csv 
     elif [[ $LINE == "sms "* ]] 
      then 
      printf "$LINE\n" >> sms_settings.csv 
     else 
      printf "$LINE\n" >> extract_clean.csv 
    fi 
done 

Mein Problem ist, dass dieses Ding am Ende eines Eintrags auf der folgenden Zeichenfolge seine Zehenstümpfe: 100%." Wenn es mit der Linie getan, es elides einfach die %." und die neue Online-Marker es folgende, und schmiert die beiden Linien zusammen:

... 100next.entry.keyname... 

ich würde gerne in erreichen und einfach manuell begrenzen die % Zeichen, aber es ist keine realistische Option für meinen Anwendungsfall. Offensichtlich vermisse ich etwas. Mein Verdacht ist, dass ich in irgendeiner Weise cat oder read in der ersten Zeile missbrauche.

Wenn es einen Ort geben sollte, hätte ich nach der Antwort suchen müssen, bevor Sie alle abgehört haben, zeigen Sie mich auf jeden Fall in diese Richtung, und ich werde mich beruhigen.

+1

printf interpretiert% nach dem Expandieren der Variablen $ LINE. Verwenden Sie stattdessen "echo". (Glaube ich) – njzk2

+0

njzk2 gewinnt die kewpie doll! Wann ist der richtige Zeitpunkt für die Verwendung von printf vs. echo? –

+0

Verwenden Sie printf, wenn Sie eine Zeichenfolge formatieren müssen, d. H. Wenn Sie die prozentualen Formatierungsfunktionen verwenden müssen. in allen anderen Fällen benutze echo – njzk2

Antwort

4

Syntax für printf ist:

printf format [argument]... 

In [ printf ] Format-String, alles gefolgt von % ist ein Formatangabe wie in dem obigen Link beschrieben. Was Sie tun möchten ist:

while read -r line; do # Replaced LINE with line, full uppercase variable are reserved for the syste, 
    if [[ "$line" = "mme "* ]] # Here* would glob for anything that comes next 
     then 
      printf "%s\n" $line >> mme_settings.csv 
     elif [[ "$line" = "sms "* ]] 
     then 
      printf "%s\n" $line >> sms_settings.csv 
     else 
      printf "%s\n" $line >> extract_clean.csv 
    fi 
done<extract.csv # Avoided the useless use of cat 
+0

Ist '' '' hier nicht falsch? Wir wollen kein Regex-Matching, nur einfaches Globbing. –

+0

@ BenjaminW. Warum globbing hier? – sjsam

+0

Wir passen nur Zeilen an, die beispielsweise mit "sms" beginnen, dem der Glob "sms" * 'entspricht.Wenn dasselbe als Regex interpretiert wird, worauf bezieht sich '*? Außerdem ist es wahrscheinlich langsamer mit der Regex-Engine. –

3

Wie erwähnt, Ihr Problem erweitert um einen Parameter eine Formatierungsanweisung in der Formatierungs Argument von printf enthält, die unter Verwendung von echo anstelle oder Bewegen der Parameter gelöst werden kann, um zu sein wie in anderen Antworten gezeigt wurde.

Ich empfehle nicht die ganze Datei mit Bash in erster Linie zu durchlaufen, da es notorisch langsam ist; Sie Extrahieren von Linien mit bestimmten Mustern beginnen, die an das ein Job ist grep zeichnet:

grep '^mme ' extract.csv > mme_settings.csv 
grep '^sms ' extract.csv > sms_settings.csv 
grep -v '^mme \|^sms ' extract.csv > extract_clean.csv 

Der dritte Befehl verwendet die -v Option (Auszug Linien, die nicht Spiel tun) und Wechsel auszuschließen Linien sowohl beginnend mit mme und sms.

+2

Dies wird viel schneller als der ursprüngliche Ansatz sein. – sjsam

+0

Danke, Leute. Letzte Woche waren es 5 Stunden mit der Hand. Ich habe es auf eine Minute (auf Kosten von Tagen, über die ich nicht reden will ...). Ja, ich weiß, dass mein Code langsam ist, aber er ist> 95% genau, und mit dem Echo vs. printf-Zeug zu fetzen sollte mich zu 100nextline D'Oh bringen! –