使用unix或awk(无sql)为列的每个唯一值选择最多N(随机或N个第一行)行

时间:2011-04-19 16:19:40

标签: unix select awk unique rows

有人会知道如何使用unix命令(或sed,awk等)为列的每个唯一值选择最多N(随机或N个第一行)行吗?请不要SQL,因为我不知道这个语言。

非常感谢你的帮助! 卡罗尔

这是一个示例输入文件:

5   00059.padded.fasta  2986
5   00059.padded.fasta  2986
5   00059.padded.fasta  2986
5   00059.padded.fasta  2986
5   00059.padded.fasta  2986
5   00059.padded.fasta  2986
6   00108.padded.fasta  2348
3   00017.padded.fasta  1769
3   00017.padded.fasta  1769
3   00017.padded.fasta  1769
3   00017.padded.fasta  1769

对于第2列中的每个给定唯一值,我想提取最多N行(对于此示例,最多2个): 预期产出:

5   00059.padded.fasta  2986
5   00059.padded.fasta  2986
6   00108.padded.fasta  2348
3   00017.padded.fasta  1769
3   00017.padded.fasta  1769

在这里,我选择了前两行,但它可以是第2列中每个唯一值的随机选择的行对。

4 个答案:

答案 0 :(得分:0)

这将为第2列中的每个唯一值返回一个恒定行数(在本例中为两个),但我很确定这不是您所期望的。您的输入数据位于“test.txt”文件中。

$ sort -k2 -u test.txt > a.tmp; sort a.tmp a.tmp
3   00017.padded.fasta  1769
3   00017.padded.fasta  1769
5   00059.padded.fasta  2986
5   00059.padded.fasta  2986
6   00108.padded.fasta  2348
6   00108.padded.fasta  2348

如果您的输入在第2列中只有一行给定的唯一值,则不清楚您的期望。如果您仍然希望输出中有两行,那么这将有效。

答案 1 :(得分:0)

#!/bin/bash
# tested with bash 4
declare -A assoc
declare -a count
while read -r line
do
    array=($line)
    assoc[ ${array[0]} ]+="${array[@]}|"
done < file
OIFS=$IFS
IFS="|"
for i in "${!assoc[@]}"
do
    count=(${assoc[$i]})
    echo "${count[@]:0:2}"
done
IFS="$OLDIFS"

@carol,这是我使用您的示例数据的输出。我使用bash 4+。如果你没有它,那么它将不适用于关联数组。

bash4> bash N.sh
6 00108.padded.fasta 2348 6 00108.padded.fasta 2348
3 00017.padded.fasta 1769 3 00017.padded.fasta 1769
5 00059.padded.fasta 2986 5 00059.padded.fasta 2986

答案 2 :(得分:0)

这是一个用于您目的的小脚本:

#!/usr/bin/ksh

awk '{ print $0 >$2".yourfile"}' yourfile
for i in *.yourfile
do
awk 'NR<=2{print}' $i
done
rm -rf *.yourfile
if [ $? -eq 0 ]
then
echo "remove temp files successful"
fi

这是执行:

torinoco!DBL:/oo_dgfqausr/test/dfqwrk12/vijay> script.sh
3   00017.padded.fasta  1769
3   00017.padded.fasta  1769
5   00059.padded.fasta  2986
5   00059.padded.fasta  2986
6   00108.padded.fasta  2348
remove temp files successful
torinoco!DBL:/oo_dgfqausr/test/dfqwrk12/vijay>

答案 3 :(得分:0)

这是我的文件test.awk。

$1 >= n {$1 = n;}
$1 <  n {$1 = $1;}
{
    for (i = 1; i<= $1; i++) {
      print $0;
    }
}

这是我的test.txt版本。假设您的测试数据具有代表性。

5   00059.padded.fasta  2986
5   00059.padded.fasta  2986
5   00059.padded.fasta  2986
5   00059.padded.fasta  2986
5   00059.padded.fasta  2986
5   00059.padded.fasta  2986
6   00108.padded.fasta  2348
3   00017.padded.fasta  1769
3   00017.padded.fasta  1769
3   00017.padded.fasta  1769
3   00017.padded.fasta  1769
1   00001.padded.fasta  1000

这是命令行,可以提供最多'n'行输出。

$ sort test.txt | uniq -c | awk -v n=2 -f test.awk  | cut -f 1 -d " " --complement
1 00001.padded.fasta 1000
3 00017.padded.fasta 1769
3 00017.padded.fasta 1769
5 00059.padded.fasta 2986
5 00059.padded.fasta 2986
6 00108.padded.fasta 2348

要更改行数,请更改指定给“n”的值。 n = 4,n = 3,等等。