выберите до N (случайных или N первых) строк для каждого уникального значения столбца, используя unix или awk (без sql) - PullRequest
0 голосов
/ 19 апреля 2011

Кто-нибудь знает, как выбрать до N (случайных или N первых) строк для каждого уникального значения столбца, используя команду unix (или sed, awk и т. Д.)? Пожалуйста, не используйте SQL, так как я не знаю этого языка.

Большое спасибо за вашу помощь! Carole

вот пример входного файла:

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

Я хотел бы извлечь до N строк (скажем, до 2 для этого примера) для каждого заданного уникального значения в столбце 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 голосов
/ 23 апреля 2011

Это мой файл 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» строк вывода.измените значение, присвоенное 'n'.n = 4, n = 3 и т. д.

0 голосов
/ 20 апреля 2011
#!/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"

@ Кэрол, это мой вывод с использованием данных вашего образца. Я использую 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
0 голосов
/ 20 апреля 2011

вот небольшой скрипт для вашей цели:

#!/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>
0 голосов
/ 20 апреля 2011

Это вернет постоянное количество строк (в данном случае две) для каждого уникального значения в столбце 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. Если вам все еще нужны две строкина выходе, тогда это будет работать.

...