2

我有文本文件,其中包含以下格式的制表符分隔列:

fileName    Type    sc1 sc2 sc3 sc4 sc5 sc6
file1   abc 0   0.2 0   0   0   0
file1   xyz 0   0.8 0   0   0.8 0.2
file2   abc 0.5 0   0   0.1 0   0
file2   xyz 0   0   0   0.7 0.003   0.1
file3   abc 0.002   0   0   0   0.04    0
file3   xyz 0.5 0   0   0   0   0.3
.
. 

第一行是标题行。sc1、sc2、sc3 等分别为 1、2、3 分(它们不全为零)

有两种以上的类型,每个文件具有相同数量的类型。

如何知道 xyz 类型的 sc6 最低的文件名? 或者如何从此文件创建另一个文本文件,该文件将具有所有 xyz 类型的文件名和 sc6?

我真的不想将它作为数据库加载或做类似的事情。我想知道我是否可以使用 Unix 的cut,sortgrep命令相当快地完成这项工作。任何 perl、awk 解决方案也可以接受。

如果问题不是很清楚,请告诉我。

PS请随时为这个问题提出不同的标题。这是我能想到的最好的。

4

2 回答 2

3

你可以像这样做一个单行:

perl -lanwe 'next unless $F[1] eq "xyz"; 
             $a{$F[0]}{$F[1]} = $F[7]; 
             }{ 
             for my $file (sort { $a{$b}{xyz} <=> $a{$a}{xyz} } keys %a) { 
                 print qq($file : $a{$file}{xyz}); }'

Autosplit-a将在空白处拆分为数组@F,同时从标准输入或参数文件名(-n开关)中读取。输入(}{“操作员”)结束后,存储的结果被排序和打印。将跳过除“xyz”之外的所有类型。

输入输出:

file1   abc 0   0   0   0   0   0
file1   xyz 0   0   0   0   0   0
file2   abc 0   0   0   0   0   0
file2   xyz 0   0   0   0   0   0
file3   abc 0   0   0   0   0   0
file4   xyz 0   0   0   0   0   1

file4 : 1
file2 : 0
file1 : 0

注意:我必须在输入中添加一行以查看它是否实际排序。对于需要排序的东西来说,多么可怕的样本数据啊!

于 2013-02-05T19:58:52.197 回答
1
awk -v lowest=9999999 '$2 == "xyz" && $8 < lowest { lowest = $8; lowfile = $1 }
                       END {print lowfile, "\t", lowest}' infile

或者:

awk '$2 == "xyz"' infile | sort -k 8n | head -1 | cut -f1,8

要为所有 xyz 创建一个只有文件名和 sc6 的文件:

awk '$2 = "xyz" {print $1, "\t", $8}' infile > outfile
于 2013-02-05T19:58:50.970 回答