awk 不会将列添加到 tab delim 文件

awk 不会将列添加到 tab delim 文件

我使用以下代码根据其他现有列的计算将两个新列(15 和 16)添加到 tab delim txt 文件中。

问题:新列数据显示在终端中,但文件未随列更新。当发送到另一个文件 ( code ... > Sample.....2.txt) 时,列会存在,但分隔符从制表符更改为空格。

需要:根据制表符分隔文件中现有列的计算,在一行代码中添加第 15 列和第 16 列。

文件:Sample1_RVDB_sort_unique.txt

代码:

awk '{$15 = ($4/$13)*100; $16 = ($4/$14)*100; print}' Sample1_RVDB_sort_unique.txt

数据

utg000001l  acc|GENBANK|MH883318.1|White    80.263  608 99  16  282 877 184245  184843  4.44e-120   438 2022    270609

答案1

如果你的输入文件是制表符分隔的,你应该将输入字段分隔符(FS,或使用 awk 的-F选项)设置为制表符(\t),否则 awk 将使用默认的 FS (一个或多个任何空格 - 请参阅默认字段分割在 GNU awk 文档中 - 但这是所有 awk 的行为,而不仅仅是gawk)。

如果您还希望输出以制表符分隔,那么您OFS也需要将输出字段分隔符 ( ) 设置为制表符,否则 awk 将使用默认的 OFS(空格)。

例如

awk -F'\t' -v OFS='\t' '{ $15 = ($4/$13)*100;
                          $16 = ($4/$14)*100;
                          print
                        }' Sample1_RVDB_sort_unique.txt

答案2

您需要告诉 awk 您的字段分隔符是什么,例如:

BEGIN { FS=OFS="\t" }

否则,它假设输入为空白链,输出为单个空白字符。

如果您的输入只有 14 个字段,那么打印附加输出字段将比在记录中创建新的 $15 和 $16 字段更有效(这将导致记录重新编译):

awk '
    BEGIN { FS=OFS="\t" }
    { print $0, ($4/$13)*100, ($4/$14)*100 }
' Sample1_RVDB_sort_unique.txt

您还应该确保 13 美元和/或 14 美元不为零,例如:

awk '
    BEGIN { FS=OFS="\t" }
    { print $0, ($13 ? ($4/$13)*100 : "Inf"), ($14 ? ($4/$14)*100 : "Inf") }
' Sample1_RVDB_sort_unique.txt

或类似的。

答案3

使用(以前称为 Perl_6)

~$ raku -ne 'my @a = .words; put join "\t", @a, (@a[3]/@a[12])*100, (@a[3]/@a[13])*100;'   file

输入示例:

utg000001l  acc|GENBANK|MH883318.1|White    80.263  608 99  16  282 877 184245  184843  4.44e-120   438 2022    270609

示例输出:

utg000001l  acc|GENBANK|MH883318.1|White    80.263  608 99  16  282 877 184245  184843  4.44e-120   438 2022    270609  30.069238   0.2246784

上面是用 Raku(Perl 编程语言家族的成员)编写的答案。命令-ne行标志告诉 Raku 以非自动打印方式在输入上逐行运行代码(“n”表示“非”)。

使用例程,输入在空格处被破坏words。该代码是where is Raku(和 Perl 的)“主题变量”.words的缩写,在本例中已设置为输入行。$_.words$_

输入被分配给@a数组,输入和附加列一起被计算/输出(在\t选项卡上连接),记住 Perl/Raku 是零索引的。

https://raku.org

相关内容