awkを使用して列を並べ替える

awkを使用して列を並べ替える

以下を使用してCSVファイルの列7を最後に移動しようとします。

awk -F '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}',OFS= "$file"

ここで、 $file はディレクトリの .csv ファイルです。しかし、出力は

awk:                          ^ syntax error

このエラーを解決する方法を知っている人はいますか?

答え1

この-Fオプションには1つの引数(フィールド区切り文字)が必要です-F,

スクリプトの終わりは(空白文字)で残りのパラメータと区別する必要がありますawk

フィールド区切り文字があり、,それを維持し、列数が一定で、11以下の場合は、次のようにします。

awk -F, '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}' OFS=, "$file"

フィールド区切り文字がセミコロンの場合は、次のように引用符で囲んで設定することを忘れないでください。

awk -f';' '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}' OFS=';' "$file"

答え2

より短い解決策は

awk -F',+' -v OFS=, '{$(NF+1)=$7; $7=""; $0=$0; $1=$1}1' file

,+すべてのバージョンで動作するかどうかはわかりませんが、少なくともGNU awkおよび互換モードawkでも動作します。-c

説明する:

  • $(NF+1)=$7:最初に行の最後に7番目のフィールドを追加します(おそらく$12=$7この場合)。
  • $7="":次のステップでは、7番目のフィールドが削除されます(ただし、周囲の区切り文字は残ります)。
  • 区切り文字を削除するには、レコード全体を並べ替える必要があります(複数のカンマをフィールド区切り文字として扱います(ここでは1回以上$0=$0実行されます))。また、以前に設定された出力フィールド強制再構築行を使用するように現在のレコードを並べ替える必要があります。区切り記号(オプションで設定)-F',+'+$1=$1-v OFS=,
  • すべてのシャッフリングが完了したら、結果を印刷する準備が整いました。1

入力例:

1,2,3,4,5,6,7,8,9,10,11

出力

1,2,3,4,5,6,8,9,10,11,7

答え3

を使用して印刷する場合は、OFS=フィールド間に区切り文字がなく、単に$7変数の値を保存して空の$7値に設定してから、行と変数を直接印刷できます。すべてのフィールドを指定する必要はありません。

$ cat file
1,2,3,4,5,6,7,8
$ awk -F, -vOFS= '{k=$7; $7=""; print $0,k}' file 
12345687

答え4

さまざまなawkバリアント(ファイルが変数内にあると仮定$file

  • ここですべての列を繰り返し、フィールド区切り記号(OFS)を使用して印刷し、行の末尾にレコードターミネーター(ORS)を印刷できます。

    awk  -F',' -v OFS=,                                \
    '{for(i=1;i<=NF;i++) if (i!=7) printf "%s",$i OFS; \
    printf "%s",$7;printf ORS}' "$file"
    
  • ここでは正規表現を使用しますgensub()機能

    gawk -F',+' -v OFS=, '{$0=gensub(/\s*\S+/,"",7) OFS $7}1' "$file"
    

    殺す7番目のフィールドを入力して行末に印刷します。

    • $0完全な記録です
    • $nn番目の記録です
    • NF現在行のフィールド数。
    • OFS出力フィールド区切り記号
    • ORS出力レコードターミネーター
    • 1trueこれはawkに通知し、デフォルト値()を印刷するトリックです$0

修正する...

7列以降のすべての列を移動できるという事実をほとんど忘れてしまいました。

awk  -F',' -v OFS=, '{tmp=$7; for(i=7;i<=NF;i++) $i=$(i+1); $NF=tmp}1 ' "$file"

関連情報