我使用以下代码根据其他现有列的计算将两个新列(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 是零索引的。