2016-03-31 19 views
2

に基づいてソートファイルは:私は私の平文ファイルをカンマで区切られたフィールドをソートする方法をハードコードしまし除いAWK:私はこの単純な<code>awk</code>コードを持っているユーザー入力

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

、素晴らしい作品。実行時にフィールドを並べ替える順番を指定できるようにしたい。

一つのハックの方法は、私がこのだったことについて考えた:

read first 
read second 
read third 

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

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

しかし、これは実際に動作しません:

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

、私はawkの能力について少し知っていますユーザー入力を受け入れる:

BEGIN { 
    getline first < "-" 
} 

$1 == first { 
} 

しかし、作成された変数がオリジナルの印刷コマンドで変数として使用できるかどうかは疑問です。より良い方法がありますか? awk$TOTALの値ではなく、文字列リテラル$TOTALを見ているように、あなたはbashawk$TOTALを拡大させる必要があり

答えて

3

は、と呼ばれています。これは、単一引用符ではなく二重引用符を使用することを意味します。

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" 

より安全な方法は、フィールド番号をawk変数として渡すことです。

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

私は他の二つの変数の '-V'を使うのを忘れていました。 – chepner

+0

ありがとう、これは素晴らしいです! – celestialroad

0

必要なのは、次のとおりです。

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)}' 

例えば:

$ 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 
関連する問題