2016-05-05 14 views
0

Ich habe einige Spalten Daten in eine Datei kopiert und dann versucht, eine Spalte Daten in eine andere Datei zu schreiben. Aber ich immer einige falscheawk im Skript zum Kopieren von Daten in eine Datei

Dies ist meine Eingabedatei: -

,E2Bn9,2015-04-29 00:00:00-0500 

['2C173'],E2BA8,2015-04-29 00:00:00-0500 

['5A475','2C174'],E2BA8,2015-06-29 00:00:00-0400 

verwendete ich den awk, sed Befehle wie folgt

sed -i 's/",/|/g' tempFile 
awk -F '[|,]' '{ print "update table set cola = " $1 " where colb = " $2 " and colc = " $3 }' tempFile > updatestmt.cql 

Ich habe die Ausgabe als

update table set cola = where colb = E2Bn9 and colc = 2015-04-29 00:00:00-0500 

update table set cola = ['2C173'] where colb = E2BA8 and colc = 2015-04-29 00:00:00-0500 

update table set cola = "['5A475' where colb = '2C174'] and colc = E2BA8 

1. zwei Zeilen scheint in Ordnung, aber letzte Zeile, es ist ein falscher Wert gedruckt.

Ich mag die letzte Zeile als

update table set cola = "['5A475','2C174'] where colb =E2BA8 and colc = 2015-06-29 00:00:00-0400 
+0

Problem mit der letzten Zeile scheint das Komma in den Klammern. Es vermischt die Feldnummerierung, wenn es in Kommas aufgeteilt wird. Geben Sie mir ein paar Minuten, um eine Alternative für die erste Sed ... –

+0

Was ist der Zweck der 'sed' Befehl vor dem awk einen? Es würde nichts an Ihrer Posted-Sample-Eingabe ändern. Wenn Sie es brauchen, dann fügen Sie den Anwendungsfall dafür in Ihre Beispieleingabe ein. Wenn Sie es nicht brauchen, dann werden Sie es los. –

Antwort

0

Die Feldtrennzeichen in den Daten, die Probleme verursachen, in der dritten Zeile genau das Komma in den Klammern sein. Eine Abhilfe könnte eine andere sed sein, dass nur , zu | außerhalb des ersten Trägers konvertiert und mit FS='|':

sed -r 's/(.*\])?.*,/\1|/g' yourfile | awk -F '|' .... 

wo .... steht für den Rest Ihres awk-Skript.

+0

Hallo Lars, ich habe es mit diesem Skript versucht, aber die Ausgabedatei bleibt leer. Es schreibt nichts in die O/P-Datei – saurav

+0

@ user5655807 Ich denke, Sie brauchen einen Befehl wie folgt: 'sed -r 's/(. * \])?. *,/\ 1 |/g' tempFile | awk -F '|' '{print' update table set cola = "$ 1" wo colb = "$ 2" und colc = "$ 3} '> updatesmt.cql'. Hier ist 'tempfile' die Eingabe. sed erzeugt output auf * stdout * und ** pipes ** es direkt in awk. awk schreibt auf stdout, das in 'updatesmt.cql' umgeleitet wird. –

4

Mit GNU awk 4. * für FPAT:

$ awk -v FPAT='([^,]*)|([[][^]]+[]])' '{print "update table set cola =", $1, "where colb =", $2, "and colc =", $3}' file 
update table set cola = where colb = E2Bn9 and colc = 2015-04-29 00:00:00-0500 
update table set cola = ['2C173'] where colb = E2BA8 and colc = 2015-04-29 00:00:00-0500 
update table set cola = ['5A475','2C174'] where colb = E2BA8 and colc = 2015-06-29 00:00:00-0400 

Siehe http://www.gnu.org/software/gawk/manual/gawk.html#Splitting-By-Content.

Bei nicht gaffen awks oder Pre-4.0-Versionen von gawk (! Ein modernes gaffen bekommen) können Sie:

$ cat tst.awk 
{ 
    delete f 
    nf = 0 
    tail = $0 
    while ((tail!="") && match(tail,/([^,]*)|([[][^]]+[]])/)) { 
     f[++nf] = substr(tail,RSTART,RLENGTH) 
     tail = substr(tail,RSTART+RLENGTH+1) 
    } 
    print "update table set cola =", f[1], "where colb =", f[2], "and colc =", f[3] 
} 

$ awk -f tst.awk file 
update table set cola = where colb = E2Bn9 and colc = 2015-04-29 00:00:00-0500 
update table set cola = ['2C173'] where colb = E2BA8 and colc = 2015-04-29 00:00:00-0500 
update table set cola = ['5A475','2C174'] where colb = E2BA8 and colc = 2015-06-29 00:00:00-0400 

Sie $0 statt f[] verwenden können, aber dann gibt es eine Performance-Overhead als Rekord wird bei jeder Zuweisung an $(++nf) erneut geteilt, und es kann Fälle geben, in denen Sie das ursprüngliche $0 später verwenden möchten.

+0

Hallo Sir, danke für die Antwort, ich habe versucht mit FPAT aber immer noch die gleiche Ausgabe wie ich bekam zuvor- ['A01WWSS2', wo colb = 'A1EEE'] ", P19S2,2015-12-15 und colc = 12: 00: 00-0500 – saurav

+0

ja .. ich benutze GNU awk. Version - GNU Awk 3.1.7 – saurav

+0

Das ist eine prähistorische Version von Gawk ohne eine Tonne von extrem nützlichen Funktionen, einschließlich FPAT (siehe http: // www. org/software/gawk/manual/gawk.html # Feature-History) Ich habe ein Skript hinzugefügt, das in diesem und anderen awks funktioniert, aber du musst wirklich eine neue Version von gawk bekommen –

0

Wenn nur Listenwerte wie in Ihrem Beispielcode angegeben sind, können Sie dieses sed versuchen;

sed "s/' *, *'/' '/g;s/\([^,]*\),\([^,]*\),\(.*\)/update table set cola = \1 where colb = \2 and colc = \3/;s/' '/','/g" file 
+0

Danke, es hat funktioniert ... danke euch allen Für Ihre Hilfe und Anregung Schätzen Sie Ihre Hilfe – saurav

+0

Gern geschehen Sie können die Antwort akzeptieren, wenn es geholfen hat – SLePort

1

wählte ich einen anderen Ansatz, so konnte ich mit zu komplex reg-exp vermeiden und es funktioniert mit jedem alten awk.

# cat tst.awk 
     {s="";} 
$1!="" {for(i=1;i<NF-1;i++)s=s (i==1?"":",") $i;} 
     {printf("update table set cola = %s where colb = %s and colc = %s\n",s,$(NF-1),$NF);} 

# awk -F, -f tst.awk yourinpfile 
update table set cola = where colb = E2Bn9 and colc = 2015-04-29 00:00:00-0500 
update table set cola = ['2C173'] where colb = E2BA8 and colc = 2015-04-29 00:00:00-0500 
update table set cola = ['5A475','2C174'] where colb = E2BA8 and colc = 2015-06-29 00:00:00-0400 

ich mit Ed darüber einig, dass ohne Schleife haben wir eine schönere Lösung, aber ich kann meine ursprüngliche Annahme wiederverwenden, dass $(NF-1) und $NF ist fix, den einfacheren reg-exp zu halten.

 {s="";} 
$1!="" {s=$0;sub("," $(NF-1) "," $NF, "", s);} 
     {printf("update table set cola = %s where colb = %s and colc = %s\n",s,$(NF-1),$NF);} 
+1

Das ist eigentlich eine gute Idee (vorausgesetzt, das erste Feld ist das einzige problematische Feld), aber es kann getan werden ohne die Schleife: 'cola = $ 0; sub (/ (, [^,] +) {2} $ /, "", Cola); Druck "Cola =", Cola, "Colb =", $ (NF-1), "Colc =", $ NF ". –

Verwandte Themen