Dataframe 是否可以使用unix删除包含特定值的列?

Dataframe 是否可以使用unix删除包含特定值的列?,dataframe,unix,awk,Dataframe,Unix,Awk,我有一个非常大的变量调用数据。我不能得出我想要的结果。 这里有一个例子 bac1 bac2 bac3 bac4 1 0 0 1 现在我想使用ubuntu命令行删除包含0的列。结果是这样的 bac1 bac4 1 1 我试过这个 awk -F "\t" -v "pat=0\t" 'NR == 2 {for (i=1; i <= NF; i++) Take[i] = (pat != $i)}{for (i =1;

我有一个非常大的变量调用数据。我不能得出我想要的结果。 这里有一个例子

bac1 bac2 bac3 bac4
1    0    0    1
现在我想使用ubuntu命令行删除包含0的列。结果是这样的

bac1    bac4
1       1
我试过这个

awk -F "\t" -v "pat=0\t" 'NR == 2 {for (i=1; i <= NF; i++) Take[i] = (pat !=  $i)}{for (i =1; i <= NF; i++) if (Take [i]) printf $i FS; print ""}'
此输出的标题为:

  #CHROM    POS ID  REF ALT QUAL    FILTER  FORMAT  EPI_ISL_422804
因此,最终输出必须如下所示:

#CHROM  POS ID  REF ALT QUAL    FILTER  FORMAT  EPI_ISL_422804
NC_045512.2 18876   NC_045512.2_18876_T_C   T   C   .   PASS    GT  1
文件不总是2行,但最多可以是4行


它不会返回头行,因为我使用了NR==2。是否有任何方法我也无法获得标题列??

如果
的话,则使用
的长版本:

awk 'NR==1{
       split($0,array,FS)
     }

     NR==2{
       s=0
       for(i=1;i<=NF;i++){
         if($i!=0){
           if(s==0){
             s=1
             printf("%s",array[i])
           }
           else{
             printf("%s%s",OFS,array[i])
           }
         }
       }
       print ""

       s=0
       for(i=1;i<=NF;i++){
         if($i!=0){
           if(s==0){
             s=1
             printf("%s",$i)
           }
           else{
             printf("%s%s",OFS,$i)
           }
         }
       }
       print ""
     }' FS='\t' OFS="\t" file
awk'NR==1{
拆分($0,阵列,FS)
}
NR==2{
s=0

对于(i=1;i,如果您的输入文件始终只有一个数据行,如示例所示,则:

$ cat tst.awk
BEGIN { FS=OFS="\t" }
NR == 1 { split($0,hdr); next }
{
    for (i = 1; i <= NF; i++) {
        if ($i != 0) {
            cols[++nf] = i
        }
    }

    for (i = 1; i <= nf; i++) {
        printf "%s%s", hdr[cols[i]], (i<nf ? OFS : ORS)
    }

    for (i = 1; i <= nf; i++) {
        printf "%s%s", $(cols[i]), (i<nf ? OFS : ORS)
    }
}
否则,如果您的输入可以有多条数据线,则需要两次通过的方法:

$ cat tst.awk
BEGIN { FS=OFS="\t" }
NR == FNR {
    if (NR > 1) {
        for (i = 1; i <= NF; i++) {
            if ($i == 0) {
                zeroCols[i]
            }
        }
    }
    next
}
FNR == 1 {
    for (i = 1; i <= NF; i++) {
        if (! (i in zeroCols) ) {
            cols[++nf] = i
        }
    }
}
{
    for (i = 1; i <= nf; i++) {
        printf "%s%s", $(cols[i]), (i<nf ? OFS : ORS)
    }
}

我会:1.转置输入。2.使用带有
0
的grep筛选行。3.再次转置输入。
输出是这样的:
如何从
bac1 bac2 bac3 bac4
获得这样的输出?这是复制和粘贴错误吗?复制了一些不相关的数据吗?
有没有办法我也无法获得标题列?
NR==1{print}NR==2{…}
这总是一个只有两行的文件吗?如果不是,我们是否应该忽略所有值都为零的列?@SHEENT否,这不会打印修改后的标题行,它会删除包含
0
的行/行,而不是删除包含
0
的列。不确定这是在收集向下投票-它有一个说明对于问题,样本输入、预期输出和OPs试图自己解决问题。是的,它也有一些不相关的实际输出,不清楚输入文件是否总是2行或可能更多,但问题的重要组成部分存在,我们使用的远远少于OPs,OPs只是2天和3天的成员这是他们的第一篇文章!实际数据是57000个sars-cov-2基因组的解析变量调用输出。也就是说,我无法提供实际数据。然后,Bac1 bac2 bac3 bac4是列的示例标题,我希望列的值为“0”要删除。示例中的bac2和bac3的值为0,因此应该删除。最后,我是新来的,这就是为什么我不能正确安排问题的原因。@KamilCukThank you@Cyrus bac1 bac4 1 1
$ cat tst.awk
BEGIN { FS=OFS="\t" }
NR == 1 { split($0,hdr); next }
{
    for (i = 1; i <= NF; i++) {
        if ($i != 0) {
            cols[++nf] = i
        }
    }

    for (i = 1; i <= nf; i++) {
        printf "%s%s", hdr[cols[i]], (i<nf ? OFS : ORS)
    }

    for (i = 1; i <= nf; i++) {
        printf "%s%s", $(cols[i]), (i<nf ? OFS : ORS)
    }
}
$ awk -f tst.awk file
bac1    bac4
1   1
$ cat tst.awk
BEGIN { FS=OFS="\t" }
NR == FNR {
    if (NR > 1) {
        for (i = 1; i <= NF; i++) {
            if ($i == 0) {
                zeroCols[i]
            }
        }
    }
    next
}
FNR == 1 {
    for (i = 1; i <= NF; i++) {
        if (! (i in zeroCols) ) {
            cols[++nf] = i
        }
    }
}
{
    for (i = 1; i <= nf; i++) {
        printf "%s%s", $(cols[i]), (i<nf ? OFS : ORS)
    }
}
$ awk -f tst.awk file file
bac1    bac4
1       1