答案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
用\t
tab 编辑,任何前导空格都用 修剪掉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