使用 awk 切换最后两个字段

使用 awk 切换最后两个字段

我正在寻找一种方法来切换制表符分隔文件的最后两个字段。字段的数量因行而异,因此我无法指定字段编号。

我在网上能找到的大部分内容都是针对特定领域的脚本。例如用 awk 交换两列

谢谢!

答案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按照所需的顺序创建了一个由空格分隔的元素 ( ) 的列表(最后两个元素已交换)。元素join\ttab 编辑,任何前导空格都用 修剪掉trim-leading,结果是 out 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

示例输出(每行的最后两个元素被交换——第一行仍然是空白):

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来引用最后一个字段,以在倒数第二个字段 ( ) 之前打印它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

一种方法可以是:

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

相关内容