Bash Awk代码说明:更改字段顺序

Bash Awk代码说明:更改字段顺序,bash,awk,field,Bash,Awk,Field,我有一个文件,一个有14列的.txt文件。它的头部看起来像这样: name A1 A2 Freq MAF Quality Rsq n Mean Beta sBeta CHi rsid SNP1 A T 0.05 1 5 56 7 8 9 11 12 rs1 SNP2 T A 0.05 1 6 55 7 8 9 11 12 rs2 我想把最后一列放在第一个位置。我不确定什么是最有效的方法,但我在其他帖子中发现

我有一个文件,一个有14列的.txt文件。它的头部看起来像这样:

name A1 A2 Freq MAF Quality Rsq n Mean Beta sBeta CHi rsid
SNP1  A  T 0.05   1       5  56 7    8    9    11  12  rs1
SNP2  T  A 0.05   1       6  55 7    8    9    11  12  rs2
我想把最后一列放在第一个位置。我不确定什么是最有效的方法,但我在其他帖子中发现了这一点:

awk '{$0=$NF FS$0; $14=""}1' file.txt | head
我得到了这个,我认为是有效的:

rsid    name A1 A2 Freq MAF Quality Rsq n Mean Beta sBeta CHi 
rs1     SNP1  A  T 0.05   1       5  56 7    8    9    11  12
rs2     SNP2  T  A 0.05   1       6  55 7    8    9    11  12
但我很难理解代码到底做了什么

我知道NF是正在处理的行的字段计数 我知道FS是场分离器 那么,我的代码究竟是如何工作的呢?我真的不明白为什么说$0整行等于NF,说FS$0不知道这意味着什么,最后一个字段现在是第一个。我确实意识到$14=并没有被写入,最终会有两个rsid列,一个在开头,一个在结尾

我对使用awk很陌生,所以如果有更简单的方法来实现这一点,我会很乐意去做


谢谢

请完成以下内容,并让我知道这是否对您有帮助

awk '{
$0=$NF FS$0;   ##Re-creating current line by mentioning $NF(last field value), FS(field separator, whose default value is space) then current line value.
$14=""         ##Now in current line(which is edited above by having last field value to very first) nullifying the last(14th field) here, you could use $NF here too(in case your Input_file have only 14 fields.
}
1              ##1 means we are making condition TRUE here and not mentioning any action so by default print action will happen.
' file.txt     ##Mentioning Input_file name here.
使用sed可能更容易

将最后一个字段与行的其余部分匹配,按相反顺序打印

\s是空白字符的简写,相当于[\t\r\n\f]。
\S是\S的否定,对于非空白。与\s等价的POSIX是[:空格:]。如果您的sed不支持速记符号,或者您希望完全可移植,您可能需要使用一种等效形式。

因此,如果我理解,$0=$NF FS$0意味着:将最后一个字段设置为整行的$0,然后使用$0作为字段分隔符。对不起,这似乎不是出于本能。我想我明白了,但我不能肯定等号是赋值。表示将新的$0设置为最后一个字段+字段分隔符+旧行。基本上都是同一个概念?编程语言。啊,我明白了。我想我被FS$0弄糊涂了。从我在终端上看到的情况来看,如果你写$0=$NF FS$0,它是一样的。非常感谢你!这只是解释了这里发生的事情的一部分,还有一部分没有解释的是这样做的负面影响:重新拆分$0、重新编译$0、尾随空格、更改格式。您应该提到,GNU仅用于\s和\s。
sed -E 's/(.*)\s(\S+)$/\2 \1/' file