用于拆分特定列的 awk 字段分隔符无法按预期工作,$0 returns 未拆分记录?

awk field separator to split specific column does not work as expected, $0 returns unsplit record?

我正在尝试通过下划线拆分记录。最初它是关于 _. 作为 FS 并且仅针对第一列。但是现在看来,根本没有分裂的作用?

cat test_file.tsv

mg.reads.per.gene_bcsZ_A1.tsv   contig_21128    476
mg.reads.per.gene_bcsZ_A1.tsv   contig_3712     1774
mg.reads.per.gene_bcsZ_A2.tsv   contig_38480    184
mg.reads.per.gene_bcsZ_A2.tsv   contig_62779    1154
mg.reads.per.gene_bcsZ_A4.tsv   contig_115486   113
mg.reads.per.gene_bcsZ_A4.tsv   contig_14345    937
mg.reads.per.gene_bcsZ_A5.tsv   contig_19362    426
mg.reads.per.gene_bcsZ_A5.tsv   contig_53656    31
mg.reads.per.gene_bcsZ_A6.tsv   contig_100190   26
mg.reads.per.gene_bcsZ_A6.tsv   contig_23343    164

而且我尝试了很多变体,例如

awk 'BEGIN { FS = _ } ; {print [=12=]}' test_file.tsv
awk 'BEGIN { FS = '_' } ; {print [=12=]}' test_file.tsv
awk 'BEGIN { FS = "_" } ; {print [=12=]}' test_file.tsv
awk 'BEGIN { FS ="_" } ; {print [=12=]}' test_file.tsv
awk  -F'_' '{print [=12=]}' test_file.tsv
awk -F"gene" '{print [=12=]}' test_file.tsv

它给出了不变的输出。我期待:

mg.reads.per.gene   bcsZ    A1.tsv   contig 21128    476
mg.reads.per.gene   bcsZ    A1.tsv   contig 3712     1774
mg.reads.per.gene   bcsZ    A2.tsv   contig 38480    184
mg.reads.per.gene   bcsZ    A2.tsv   contig 62779    1154
mg.reads.per.gene   bcsZ    A4.tsv   contig 115486   113
mg.reads.per.gene   bcsZ    A4.tsv   contig 14345    937
mg.reads.per.gene   bcsZ    A5.tsv   contig 19362    426
mg.reads.per.gene   bcsZ    A5.tsv   contig 53656    31
mg.reads.per.gene   bcsZ    A6.tsv   contig 100190   26
mg.reads.per.gene   bcsZ    A6.tsv   contig 23343    164

我是不是漏掉了什么明显的东西?

编辑:是的,我做了:"It is a common error to try to change the field separators in a record simply by setting FS and OFS, and then expecting a plain ‘print’ or ‘print [=32=]’ to print the modified record."(awk 手册,"understanding [=33=]")

编辑:并达到最终目标(用 _ 和 . 分隔,仅在第一列中有效(至少在一行中以“;”分隔):

    awk 'BEGIN { OFS = "\t" }
  {
  split (, a, "_") 
  split (a[3], b, "\.") 
  print , a[2], b[1]
  }' test_file.tsv

输出:

contig_21128    bcsZ    A1
contig_3712     bcsZ    A1
contig_38480    bcsZ    A2
contig_62779    bcsZ    A2
contig_115486   bcsZ    A4
contig_14345    bcsZ    A4
contig_19362    bcsZ    A5
contig_53656    bcsZ    A5
contig_100190   bcsZ    A6
contig_23343    bcsZ    A6

您误解了 Awk 中字段分隔符的使用。 Awk 的字段分隔符告诉 Awk 使用什么值来划分输入中的列,默认为空白。

为了帮助您了解正在发生的事情,下面是您目前正在做的事情(我已将数据文件减少到只有 3 行以便于管理):

$awk -F "_" '{print [=10=]}' test_file.tsv
mg.reads.per.gene_bcsZ_A1.tsv   contig_21128    476
mg.reads.per.gene_bcsZ_A1.tsv   contig_3712     1774
mg.reads.per.gene_bcsZ_A2.tsv   contig_38480    184
$awk -F "_" '{print }' test_file.tsv
mg.reads.per.gene
mg.reads.per.gene
mg.reads.per.gene
$awk -F "_" '{print }' test_file.tsv
bcsZ
bcsZ
bcsZ
$awk -F "_" '{print }' test_file.tsv
A1.tsv   contig
A1.tsv   contig
A2.tsv   contig
$awk -F "_" '{print }' test_file.tsv
21128    476
3712     1774
38480    184

看,您已经将输出分成 4 列,每次出现下划线时都将其分开,在 awk 中为 </code>、<code></code>,和 <code>。请注意 [=16=] returns 所有由字段分隔符连接的列,看起来就像您的初始输入。

您想要的是将所有下划线换成空格,这样看起来就有 6 列。这可以通过使用 tr 命令非常容易地完成:

$ tr '_' ' ' < test_file.tsv 
mg.reads.per.gene bcsZ A1.tsv   contig 21128    476
mg.reads.per.gene bcsZ A1.tsv   contig 3712     1774
mg.reads.per.gene bcsZ A2.tsv   contig 38480    184

现在您已经有了六列,如果您愿意,可以将输出输入到 awk 中,然后再做任何您想做的事情。

[=12=] 是 awk 中的整行。

 awk -F_ '{=;print}' sample.csv

输入字段分隔符为 _,默认输出字段分隔符为 space。 {=;print} 根据输出分隔符重建字段并全部打印。

输出:

mg.reads.per.gene bcsZ A1.tsv   contig 21128    476
mg.reads.per.gene bcsZ A1.tsv   contig 3712     1774
mg.reads.per.gene bcsZ A2.tsv   contig 38480    184
mg.reads.per.gene bcsZ A2.tsv   contig 62779    1154
mg.reads.per.gene bcsZ A4.tsv   contig 115486   113
mg.reads.per.gene bcsZ A4.tsv   contig 14345    937
mg.reads.per.gene bcsZ A5.tsv   contig 19362    426
mg.reads.per.gene bcsZ A5.tsv   contig 53656    31
mg.reads.per.gene bcsZ A6.tsv   contig 100190   26
mg.reads.per.gene bcsZ A6.tsv   contig 23343    164