【问题标题】:My awk script not using all lines of input我的 awk 脚本没有使用所有输入行
【发布时间】:2015-02-25 00:36:53
【问题描述】:

仅供参考:$NEWFILE 是 newfile.vcf

awk 'BEGIN {FS="[\t]+"}; NR <= 2 || $6 >= 100 {print $0 > "newfile.vcf"}'
$NEWFILE

这是我的 awk 代码。我有一个数据列表,第 6 列必须大于等于 100。我也想忽略前 2 行。
数据由制表符分隔,但以新行结束。我的代码只处理一行数据,恰好有第 6 列大于 100。(但是,它确实忽略了前 2 行),然后停止。其余的行没有出现在 newfile.vcf 我猜是因为新行。无论如何我该如何解决这个问题?

输入:

                                                     NAME1    NAME2    NAME3
#CHROM   POS    ID    ALT    REF   QUAL   FILTER    953_102   953_103    953_104
Chr1    1058     .     TAA    TAAA    999   StandBias
Chr1    1071     .     TAA    TAAA    118   StandBias
Chr1    1084     .     TAA    TAAA    27.5  StandBias
Chr1    1089     .     TAA    TAAA    999   StandBias

期望的输出:

                                                     NAME1    NAME2    NAME3
#CHROM   POS    ID    ALT    REF   QUAL   FILTER    953_102   953_103    953_104
Chr1    1058     .     TAA    TAAA    999   StandBias
Chr1    1071     .     TAA    TAAA    118   StandBias
Chr1    1089     .     TAA    TAAA    999   StandBias

当前输出:

                                                     NAME1    NAME2    NAME3
#CHROM   POS    ID    ALT    REF   QUAL   FILTER    953_102   953_103    953_104
Chr1    1058     .     TAA    TAAA    999   StandBias

程序(尽管 awk 之前的内容与问题无关。awk 之前的所有内容都按预期工作。)

#! /bin/bash
#removing the extra stuff at the top of datafile.
NEWFILE=newfile.vcf
LINESINLEGEND=`wc legend.txt | awk {'print $1'}`
LINESINLEGEND=$((LINESINLEGEND-1))
NEWLEGEND=`tail -n$LINESINLEGEND $2`

if [ $# -eq 0 ]
then
    echo "usage: filename.vcf <optional>legend.txt"
fi

if [ $# -eq 2 ]
then
    printf "$NEWLEGEND" > temp
    CUTME=`cut -f 5 temp | cut -d " " -f 4 temp | tr -s '\n' '\t'`
    rm temp
    printf "" > $NEWFILE
    printf "\t" >> $NEWFILE
    printf "\t" >> $NEWFILE
    printf "\t" >> $NEWFILE
    printf "\t" >> $NEWFILE
    printf "\t" >> $NEWFILE
    printf "\t" >> $NEWFILE
    printf "\t" >> $NEWFILE
    printf "\t" >> $NEWFILE
    printf "\t" >> $NEWFILE
    printf "$CUTME\n" >> $NEWFILE

    grep -v "^\#\#" $1 >> $NEWFILE
    awk 'NR==1 || $6 >= 100' newfile.vcf > newfile.vcf
    #suggested code makes nothing appear in newfile.vcf
fi

【问题讨论】:

  • 我想知道这个命令是如何工作的!请从您的输入和预期输出中发布一些示例行。
  • 添加输入输出
  • 使用 awk 'NR==1 || $6 >= 100' newfile.vcf > newfile.vcf 现在什么都不打印了。

标签: bash shell unix awk


【解决方案1】:

这个命令应该可以做到:

awk 'NR==1 || $6 >= 100' input.file > newfile.vcf

NR==1 匹配输入的第一行。 $6 &gt;= 100 匹配那些QUAL 大于或等于100 的行。 awk 中的默认操作是将输入的整个过程打印到输出。这就是为什么你可以省略{print $0}

您无需将TAB 指定为分隔符,因为它是默认分隔符之一。

【讨论】:

  • 您好,感谢您的建议,但是我的程序在使用该命令后挂起。
  • 您的代码有效,我刚刚创建了一个临时文件并将其用作输入。谢谢。
【解决方案2】:

我认为这应该可以解决问题:

 awk -F"\t" '{if ( $6 > 100 || NR<=2) print $0}' input.vcf > newfile.vcf

当然,使用 awk 有很多方法可以给猫剥皮。除了将 $6 令牌写为 6$ 之外,您的脚本确实应该可以工作。如果我刚刚编写的这个脚本做同样的事情,那么可能不是您输入文件中的所有行都是制表符分隔的。

【讨论】:

  • 对不起,我手动重写了命令,在我的机器上是 6 美元。我试过你的代码,我的 newfile.vcf 是空白的。但也许你是对的,并不是所有的行都用制表符分隔,很难说有这么多数据。
  • 在命令行上尝试awk -F"\t" '$6!="" || NR&lt;=3' yourinput.file | wc -l 这将计算 awk 返回的没有 NULL $6 令牌或在前两条记录中的记录(建议该行不是制表符分隔)。比较一下wc -l yourinputfile.txt如果两者不匹配,那么你就有问题了。
  • 您不需要传递-F"\t"。默认是分隔符
  • @anton5999 你在告诉your program hangs。请展示你的程序。
  • 嗨 JNevill,这两个命令是不同的。第一个产生 85 而第二个产生 147。另外 hek2gml 我现在将发布程序,只需要解释它的作用。
猜你喜欢
  • 2013-02-28
  • 2021-11-29
  • 1970-01-01
  • 2011-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多