用于拆分特定列的 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
我正在尝试通过下划线拆分记录。最初它是关于 _
和 .
作为 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