我有一个文本文件(例如):
apple V$NFY_Q6_rc V=0.741
apple V$HOXA7_01_rc V=0.454
apple V$ALPHACP1_01_rc V=0.695
orange V$SP4_Q5 V=0.747
grapes V$SP1_Q2_01 V=0.677
grapes V$SP1_Q6_01_rc V=0.685
grapes V$SP1_Q6_rc V=0.884
我想提取每个水果具有最高 V 值(在第 3 列)的行。我的输出应该如下所示:
apple V$NFY_Q6_rc V=0.741
orange V$SP4_Q5 V=0.747
grapes V$SP1_Q6_rc V=0.884
我在不同的子目录中有几个这样的文件。
子集化后,我将使用以下代码来获取第 2 列中特定字符串出现的次数。
perl -lanE '$str=$F[1]; $f="/home/$str/list/$str.txt"; $c=`grep -c "$str" "$f"`;chomp($c);$x=0;$x++ if $c;say "$str\t$x\t$c"' file2
这将产生以下输出。假设我正在该文件的第 2 列中搜索字符串“SP4”:
X X in file? number of times it occurs
NFA 0 0
SP4 1 2
NFATC1 0 0
我想要 V 值(上面的值与此表一起包含在内)
X X in file? number of times it occurs V value
NFA 0 0
SP4 1 2 0.747
NFATC1 0 0
PS:关于中间的perl程序的更多详细信息,请参考这个链接:
http://stackoverflow.com/questions/23109490/search-for-occurrence-of-a-string-in-another-file-in-a-particular-column
答案1
如果顺序不重要,两次传递sort
就可以了。在第一遍中,按字段 1 排序,然后按字段 3 的数字部分(起始位置 4)进行反向排序。该-b
修饰符会导致前导空格被忽略。将此管道传递给第二个sort
,为字段 1 中的每个唯一值返回一条记录,但这次指定 stable sort( -s
) 修饰符以确保字段 3 中具有最高值的记录(该记录已冒泡到每个值的顶部)在字段 1 中,返回先前的排序)
sort -k1,1 -k3.4b,3nr file.txt | sort -k1,1 -s -u
apple V$NFY_Q6_rc V=0.741
grapes V$SP1_Q6_rc V=0.884
orange V$SP4_Q5 V=0.747
答案2
和awk
:
awk -F'[ =]' '$NF>a[$1]{a[$1]=$NF;b[$1]=$0}END{for (i in b) print b[i]}' filename.txt
这是通过创建 V 值的数组 a 来实现的,该数组由第一列索引。对于每一行,将 V 值与该索引的数组的当前值进行比较,如果它更大,则更新数组中的值并将整行存储在第二个数组 b 中。处理完整个文件后,将打印 b 中的所有内容。
输出示例:
orange V$SP4_Q5 V=0.747
apple V$NFY_Q6_rc V=0.741
grapes V$SP1_Q6_rc V=0.884
如果顺序很重要,您可以通过管道传输sort
(例如,按 V 号排序):
awk -F'[ =]' '$NF>a[$1]{a[$1]=$NF;b[$1]=$0}END{for (i in b) print b[i]}' filename.txt | sort -t= -nk2
给出:
apple V$NFY_Q6_rc V=0.741
orange V$SP4_Q5 V=0.747
grapes V$SP1_Q6_rc V=0.884
答案3
这是一个解决方案perl
:
$ perl -F'\s+|=' -anle '
$h{$F[0]} = [$F[-1],$_] if $F[-1] > $h{$F[0]}->[0];
END {print $h{$_}->[1] for keys %h}' file
grapes V$SP1_Q6_rc V=0.884
apple V$NFY_Q6_rc V=0.741
orange V$SP4_Q5 V=0.747
更新
假设运行两个单行代码后有两个结果。
file1
:
apple V$NFY_Q6_rc V=0.741
orange V$SP4_Q5 V=0.747
grapes V$SP1_Q6_rc V=0.884
file2
:
X X in file? number of times it occurs
NFA 0 0
SP4 1 2
NFATC1 0 0
你可以试试这个:
$ awk -F'[ =]+' 'FNR==NR{a[$2]=$NF;next}
FNR==1{print $0"\tV value";next}
{for(i in a){
if(index(i,$1)){
print $0"\t"a[i];
next;
}
}
print;
}' file1 file2
X X in file? number of times it occurs V value
NFA 0 0
SP4 1 2 0.747
NFATC1 0 0