awkを使用して最後の2つのフィールドを切り替える

awkを使用して最後の2つのフィールドを切り替える

タブ区切りファイルの最後の2つのフィールドを切り替える方法を探しています。フィールド数は行ごとに異なるため、フィールド番号を指定することはできません。

オンラインで見つけることができるほとんどのものはドメイン固有のスクリプトです。例えばawkを使用した2つの熱交換

ありがとうございます!

答え1

awk -F"\t" -v OFS="\t" 'NF>1 {t=$(NF-1); $(NF-1)=$NF; $NF=t} {print}' file

フィールドが2つ以上の場合にのみ、および$NF間の標準交換が可能です。$(NF-1)-1フィールドへのアクセスは致命的なエラーです(空白行の場合NF==0)。

また見なさい:GNU awkフィールド

答え2

使用幸せ(以前のPerl_6)

raku -ne 'join( "\t", .words[0..*-3], .words[*-1] // "", .words[*-2] // "").trim-leading.put ;' 

デフォルトでは、上記のコードはスペースでwords区切られた要素()のリストを目的の順序で生成します(最後の2つの要素が置き換えられます)。要素はタブjoin\t編集され、先行スペースが切り捨てられ、trim-leading結果としてアウトになりますput。このコードは、タブで区切られた列だけでなく、スペースで区切られた列でも機能します。

//Rakuで定義されたOR演算子は、文字列Nilコンテキストの値の問題を回避するために使用されます。""必要に応じて空の文字列を「挿入」します。

入力例(最初の行は空です):

A
A   B
A   B   C
A   B   C   D
A   B   C   D   E
A   B   C   D   E   F

出力例(各行の最後の2つの要素が置き換えられました。最初の行はまだ空です):

A   
B   A
A   C   B
A   B   D   C
A   B   C   E   D
A   B   C   D   F   E

https://docs.raku.org/routine/words
https://docs.raku.org/routine/join
https://raku.org

答え3

組み込み変数を使用して、NF最後のフィールドを参照して、最後の2番目のフィールド()の前に印刷できますNF-1

awk 'NF <= 1; NF > 1 {for (i = 1; i <= NF-2; i++) printf "%s\t", $i; print $NF"\t"$(NF-1)}' file.tsv

答え4

1つのアプローチは次のとおりです。

awk -F '\t' '
BEGIN {OFS=FS}
f=(NF>1){
  p = length-length($(NF-1)"x"$NF)
  print substr($0,1,p) $NF, $(NF-1)
}!f' file

関連情報