タブ区切りファイルの最後の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