【问题标题】:Replace fields smaller than 1, then filter rows with values greater than 1替换小于 1 的字段,然后过滤值大于 1 的行
【发布时间】:2014-09-15 22:24:38
【问题描述】:

我一直在尝试过滤一些我拥有很长时间的 csv 文件。几乎是手工完成的,因为我不知道为什么我的脚本不起作用。希望你们能弄清楚我做错了什么。

我有以下文件:csv file

我可以使用以下 sed 脚本替换小于 1 的值:

sed -e 's/[0][0-9]*\.[0-9]*/0/g'  genes.csv > genes-filtered1.csv

在下一步中,我想删除所有全为零的行。但是,如果它们在至少一列中的值大于 1,我想保留。我尝试了几个脚本,但都不起作用。

以下是其中的一些:

awk '{ if ($2 > 1 || $3 > 1 || $4 > 1 || $5 > 1 || $6 > 1 || $7 > 1 || $8 > 1 || $9 > 1 || $10 > 1 || $11 > 1 || $12 > 1 || $13 > 1) print $0 }' genes-filtered1.csv > genes-filtered2.csv 

或者只是尝试使用阈值按一列过滤:

threshold=1
awk -v threshold=$threshold '$3 > threshold' genes-filtered1.csv > genes-filtered2.csv

我也试过了:

awk '{ for (i=2; i<=NF; i++) { if ($i != 0) { print; next } } }' genes-filtered1.csv > genes-filtered2.csv

我终于尝试了:

awk '{for (i=2;i<=NF;i++) if ($i>=1){print $0;next}}' genes-filtered1.csv > genes-filtered2.csv

问题是输出文件要么是空的,要么与原始文件相同。任何如何解决它的建议将不胜感激。还有可能有一个 awk 命令来做我正在用 sed 做的事情,然后删除全零的行吗? 谢谢

【问题讨论】:

    标签: csv awk sed


    【解决方案1】:
    awk '
    BEGIN{ FS=OFS="," }
    NR > 1 {
        allZeros = 1
        for (i=2; i<=NF; i++) {
            if ($i < 1) {
                $i = 0
            }
            else {
                allZeros = 0
            }
        }
    }
    !allZeros
    ' file
    

    【讨论】:

    • 谢谢。最初它不起作用。但是问题出在我的文件中。在做了@jaypal 下面所说的(使用dos2unix)之后,它就可以工作了。谢谢。
    • @degopwn 您应该使用并接受此解决方案。我还没有测试过,但我确信它会更有效,因为它只会迭代行一次,从而提高性能。
    【解决方案2】:

    当您使用awk 时,您实际上不需要使用sed。当任何一个字段大于1 时,以下解决方案将启用标志f。如果标志为真,那么我们将再次遍历字段并将所有小于1 的值转换为0

    awk '
    BEGIN { FS = OFS = "," }         # Set input and output field separator to ,
    {
        for (i=2; i<=NF; i++) 
            if ($i >= 1) { f = 1 }   # Enable a flag when any one field is greater than 1
    }
    f {
        for (i=2; i<=NF; i++) { 
            $i = ($i < 1 ? 0 : $i)   # If the flag is true convert values < 1 to 0
        }
        f = 0;                       # Set the flag to false
        print                        # Print the line
    }' file
    

    【讨论】:

    • 您好,谢谢。我首先需要将小于 1 的值转换为零(这是一个基因被认为表达的阈值)。然后我需要检查所有样本(列)以确保基因在至少一个样本中表达。然后我用它用 Lattice 绘制一个格子图。不知何故,根据您的建议,它可以工作,但会更改文件的格式。它打印前两行,然后将所有其他行放在它前面。最好的。
    • @degopwn 看起来您的文件包含控制字符。您可以通过cat -vet filename 运行您的文件,看看是否找到任何^M 字符。如果是这样,那么您可能需要在文件上执行 dos2unix 以将 windows 行尾转换为 unix 行尾
    • 是的,它有很多。现在它正在工作。非常感谢。
    猜你喜欢
    • 2019-06-11
    • 2015-04-22
    • 1970-01-01
    • 1970-01-01
    • 2022-07-07
    • 1970-01-01
    • 2012-11-15
    • 2018-12-14
    • 1970-01-01
    相关资源
    最近更新 更多