Csv 替换小于1的字段,然后筛选值大于1的行

Csv 替换小于1的字段,然后筛选值大于1的行,csv,awk,sed,Csv,Awk,Sed,我一直在尝试过滤一些csv文件,我有很长一段时间。因为我不明白为什么我的脚本不起作用,所以几乎都是手工完成的。希望你们能找出我做错了什么 我有以下文件: 我可以使用以下sed脚本替换小于1的值: sed -e 's/[0][0-9]*\.[0-9]*/0/g' genes.csv > genes-filtered1.csv 在下一步中,我将删除所有具有全零的行。但是,如果它们在至少一列中的值大于1,我希望保留该值。我尝试了几个脚本,但都不起作用 以下是其中一些: awk '{ if (

我一直在尝试过滤一些csv文件,我有很长一段时间。因为我不明白为什么我的脚本不起作用,所以几乎都是手工完成的。希望你们能找出我做错了什么

我有以下文件:

我可以使用以下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当您使用
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
awk'
开始{FS=OFS=“,”}#将输入和输出字段分隔符设置为,
{
对于(i=2;i=1){f=1}#当任何一个字段大于1时启用标志
}
f{

对于(i=2;i当您使用
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
awk'
开始{FS=OFS=“,”}#将输入和输出字段分隔符设置为,
{
对于(i=2;i=1){f=1}#当任何一个字段大于1时启用标志
}
f{
对于(i=2;i
awk'
开始{FS=OFS=“,”}
NR>1{
全零=1
对于(i=2;i
awk'
开始{FS=OFS=“,”}
NR>1{
全零=1

对于(i=2;iHi谢谢。我需要首先将小于1的值转换为零(这是基因被认为是表达的阈值)。然后我需要检查所有样本(列)确保基因至少在一个样本中表达。然后我用它绘制一个带有晶格的网格图。根据你的建议,它可以工作,但改变了文件的格式。它打印前两行,然后将所有其他行放在前面。最好。@degopn看起来你的文件有控制字符。你能运行你的文件吗通过
cat-vet filename
查看是否找到
^M
字符。如果是这样,您可能需要对文件执行
dos2unix
以将windows行结尾转换为unix行结尾是的,它有很多。现在它正在工作。非常感谢。您好,谢谢。我需要首先将小于1的值转换为零(这是基因表达的阈值)。然后我需要检查所有样本(列)确保基因至少在一个样本中表达。然后我用它绘制一个带有晶格的网格图。根据你的建议,它可以工作,但改变了文件的格式。它打印前两行,然后将所有其他行放在前面。最好。@degopn看起来你的文件有控制字符。你能运行你的文件吗通过
cat-vet filename
查看是否找到
^M
字符。如果是这样,您可能需要在文件上执行
dos2unix
以将windows行结尾转换为unix行结尾是的,它有很多。现在它正在工作。非常感谢。谢谢。最初它不起作用。但是问题在我的文件中在完成@jaypal下面所说的操作后(使用dos2unix)它是有效的。谢谢。@degopn您应该使用并接受此解决方案。我还没有测试过,但我确信它更有效,因为它只会迭代一次行,从而提高性能。谢谢。最初它不起作用。但是问题出在我的文件中。在执行@jaypal下面所说的操作之后(使用dos2unix)它是有效的。谢谢。@degopn您应该使用并接受这个解决方案。我还没有测试过,但我确信它更有效,因为它只迭代一次行,从而提高了性能。
awk '
BEGIN{ FS=OFS="," }
NR > 1 {
    allZeros = 1
    for (i=2; i<=NF; i++) {
        if ($i < 1) {
            $i = 0
        }
        else {
            allZeros = 0
        }
    }
}
!allZeros
' file