awk 选择文件中存在 $1 的行并使用更改的字段输出

awk choose a line with $1 present in a file and output with a changed field

我试过使用 Awk 来做以下事情: 我有一个大的 txt 文件,第一列是一个基因的名称,每列都有不同的值,基本上是数字。 现在我有一个文件,其中包含我要修改的基因列表(不是所有基因,只是一个子集)。

最初我只是使用我在论坛中找到的东西删除了行

awk -F '\t' ' FILENAME=="gene_list" {arr[]; next}  # create an array without values 
        !( in arr)' gene_list original_file.txt > modified_file.txt

效果很好,但现在我需要保留所有行(以相同的顺序),但修改这些基因以执行如下操作:

if ( in arr) {print , , -(/10), }
else {print [=11=]}

所以你看,这一次,如果不同(基因不在我的列表中),我想保留整行,否则我想保留整行但修改一列中的值给定的数字。

如果您可以包含一些内容以使该值保持为整数,那就太好了。如果该值变为负数,我还必须替换为 0。但我知道该怎么做,至少在一个单独的命令中。

编辑:最小示例: txt 文件中的基因列表,一个在另一个下面:

ccl5
cxcr4
setx

要修改的文件:(我在这里用逗号作为字段分隔符,但应该有制表符来分隔字段)

ccl4,3,18000,50000
ccl5,4,400,5000
cxcr4,5,300,2500
apoe,4,100,90
setx,3,200,1903

预期输出:(当第一列中的基因与我单独的 txt 文件中的基因匹配时,我删除了第 4 列的第 10 列,否则我保持整行不变)

ccl4,3,18000,50000
ccl5,4,0,5000
cxcr4,5,50,2500
apoe,4,100,90
setx,3,10,1903

只需说明算术约束。

以下尝试用惯用的 Awk 表达它。

if (something) { print } 可以重新表述为 something。因此,1(始终为真)是“打印所有行(如果您在脚本中到达此点之前点击 next)的常见习语。

可以使用 sprintf("%1.0f", n) 对浮点数进行舍入,如果分数大于 0.5,则可以正确地向上舍入(int(n) 总是向下舍入)。

awk 'BEGIN { FS=OFS="\t" }
  FILENAME=="gene_list" {arr[]; next}
   in arr { x=sprintf("%1.0f", -(/10));
    if (x<0) x=0; print , , x, ; next }
  1' gene_list original_file.txt > modified_file.txt

演示:https://ideone.com/oDjKhf