2016-03-31 16 views
2

Ich habe diesen einfachen awk Code:awk: Art-Datei basierend auf Benutzereingaben

awk -F, 'BEGIN{OFS=FS} {print $2,$1,$3}' $1

Funktioniert prima, außer ich fest einprogrammiert habe, wie ich die kommagetrennte Felder meiner Klartextdatei sortiert werden soll. Ich möchte zur Laufzeit angeben können, in welcher Reihenfolge ich meine Felder sortieren möchte.

Ein hacky Weg dachte ich über das tun dies war:

read first 
read second 
read third 

TOTAL=$first","$second","$third 

awk -F, 'BEGIN{OFS=FS} {print $TOTAL}' $1 

Aber das funktioniert nicht wirklich:

awk: illegal field $(), name "TOTAL"

Auch ich weiß ein wenig über awk ‚s Fähigkeit Benutzereingaben akzeptieren:

BEGIN { 
    getline first < "-" 
} 

$1 == first { 
} 

Aber ich frage mich, ob die erstellten Variablen wiederum als Variablen im ursprünglichen Druckbefehl verwendet werden können? Gibt es einen besseren Weg?

Antwort

3

Sie haben zu lassen bash erweitern $TOTAL vor awk genannt wird, so dass awk den Wert von $TOTAL sieht, nicht die Zeichenkette $TOTAL. Dies bedeutet, doppelte, nicht einzelne Anführungszeichen zu verwenden.

read first 
read second 
read third 

# Dynamically construct the awk script to run 
TOTAL="\$$first,\$$second,\$$third" 
SCRIPT="BEGIN{OFS=FS} {print $TOTAL}" 

awk -F, "$SCRIPT" "$1" 

Ein sichereres Verfahren ist die Feldnummern awk Variablen zu übergeben.

awk -F, -v c1="$first" -v c2="$second" -v c3="$third" 'BEGIN{OFS=FS} {print $c1, $c2, $c3}' "$1" 
+0

ich vergessen zu '-V' für die beiden anderen Variablen. – chepner

+0

Danke, das ist großartig! – celestialroad

0

Alles, was Sie brauchen, ist:

awk -v order='3 1 2' 'BEGIN{split(order,o)} {for (i=1;i<=NF;i++) printf "%s%s", $(o[i]), (i<NF?OFS:ORS)}' 

z.B .:

$ echo 'a b c' | awk -v order='3 1 2' 'BEGIN{split(order,o)} {for (i=1;i<=NF;i++) printf "%s%s", $(o[i]), (i<NF?OFS:ORS)}' 
c a b 

$ echo 'a b c' | awk -v order='2 3 1' 'BEGIN{split(order,o)} {for (i=1;i<=NF;i++) printf "%s%s", $(o[i]), (i<NF?OFS:ORS)}' 
b c a 
Verwandte Themen