使用制表符作为字段分隔符在 awk 内排序

Jos*_*osh 4 awk sort

我想按特定字段对制表符分隔的文件进行排序,同时保留标题。awk我按照此处所述使用sort 和 uniq in awk,但我不知道该告诉谁sort字段分隔符是制表符。

玩具数据:

$ echo -e "head_1\thead_2\thead_3" > file.tsv
$ echo -e "aaa zzz\tc\t300" >> file.tsv
$ echo -e "bbb yyy ooo\ta\t100" >> file.tsv
$ echo -e "ccc xxx nnn\tb\t200" >> file.tsv
$ column -ts $'\t' file.tsv
head_1       head_2  head_3
aaa zzz      c       300
bbb yyy ooo  a       100
ccc xxx nnn  b       200

$ awk -F'\t' 'NR==1; NR>1 { print | "sort -k2" }' file.tsv | column -ts $'\t' 
head_1       head_2  head_3
ccc xxx nnn  b       200           ## note these data are sorted 
bbb yyy ooo  a       100           ## based on the xxx/yyy/zzz 
aaa zzz      c       300           ## not the a/b/c
Run Code Online (Sandbox Code Playgroud)

当我尝试明确告诉sort字段分隔符是制表符时,我收到此错误,我认为这与引用问题有关:

$ awk -F'\t' 'NR==1; NR>1 { print | "sort -k2 -t $'\t'" }' file.tsv | column -ts $'\t'
sort: option requires an argument -- 't'
Try 'sort --help' for more information.
head_1  head_2  head_3
Run Code Online (Sandbox Code Playgroud)

如何指定sort`awk 内部的列分隔符?谢谢

SE 的 Web 界面在语法高亮方面比 Notepad++ 做得更好;这是我尝试过的一些事情:

$ awk -F'\t' 'NR==1; NR>1 { print | "sort -k2 -t $'$'\t''" }' file.tsv | column -ts $'\t'
head_1       head_2  head_3
aaa zzz      c       300
bbb yyy ooo  a       100
ccc xxx nnn  b       200


$ awk -F'\t' 'NR==1; NR>1 { print | "sort -k2 -t $'\t'" }' file.tsv | column -ts $'\t'
sort: option requires an argument -- 't'
Try 'sort --help' for more information.
head_1  head_2  head_3

$ awk -F'\t' 'NR==1; NR>1 { print | "sort -k2 -t "'$'\t''"" }' file.tsv | column -ts $'\t'
sort: option requires an argument -- 't'
Try 'sort --help' for more information.
head_1  head_2  head_3

$ awk -F'\t' 'NR==1; NR>1 { print | "sort -k2 -t "'$'\t'' }' file.tsv | column -ts $'\t'
sort: option requires an argument -- 't'
Try 'sort --help' for more information.
head_1  head_2  head_3
Run Code Online (Sandbox Code Playgroud)

αғs*_*нιη 5

选择以下选项之一:

\n\n
... | "sort -k2 -t \\\\\\t "\n
Run Code Online (Sandbox Code Playgroud)\n\n\n\n
... | "sort -k2 -t \\"\\t\\" "\n
Run Code Online (Sandbox Code Playgroud)\n\n\n\n
... | "sort -k2 -t\'\\\'\'\\t\'\\\'\' "\n
Run Code Online (Sandbox Code Playgroud)\n\n\n\n
... | "sort -k2 -t \\047\\011\\047" ## preferred \n
Run Code Online (Sandbox Code Playgroud)\n\n

\\011是制表符/\\047单引号 \'的八位字节 ASCII 代码

\n\n\n\n
awk -v q="\'" ... { print | "sort -k2 -t " q "\\t" q }\'\n
Run Code Online (Sandbox Code Playgroud)\n\n\n\n
awk -v tb="\'\\t\'" ... { print | "sort -k2 -t " tb }\'\n
Run Code Online (Sandbox Code Playgroud)\n\n\n\n
awk -v tb=$\'\\t\' ... { print | "sort -k2 -t \\"" tb "\\"" }\'\n
Run Code Online (Sandbox Code Playgroud)\n\n\n\n
awk -v tb=$\'\\t\' -v q="\'" ... { print | "sort -k2 -t " q tb q }\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

还有更多\xe2\x80\xa6;阅读awk 中的 Shell 引用问题;另请参见awk 中的转义序列

\n