У меня есть небольшой фрагмент файла, с которым я работаю:
ENSDARG00000032737 ENSDARP00000120731
ENSDARG00000032737 ENSDARP00000049290
ENSDARG00000061051 ENSDARP00000081062
ENSDARG00000061051
ENSDARG00000061051 ENSDARP00000129708
Я хочу вывести только первый экземпляр каждого уникального значения в первом столбце и соответствующее значение во втором столбце, поэтому мой желаемый вывод будет следующим:
ENSDARG00000032737 ENSDARP00000120731
ENSDARG00000061051 ENSDARP00000081062
Есть ли простой способ сделать это с помощью awk, uniq или чего-то подобного?
Любая помощь будет оценена по достоинству.
решение1
POSIX-AWK:
m1[$1] == 0 {
m1[$1] = 1
print
}
Для каждой строки:
- посмотрите, существует ли первый столбец в «базе данных»
- если нет, добавьте в «базу данных» и выведите всю строку
решение2
$ sort -s -k1,1 -u file
ENSDARG00000032737 ENSDARP00000120731
ENSDARG00000061051 ENSDARP00000081062
Это сортирует файл только по первому столбцу. При этом игнорируются строки, первый столбец которых уже был виден.
Большинство реализаций sort
имеют нестандартную -s
опцию (используемую в команде выше), которая гарантирует, что будет использоваться "стабильный" алгоритм сортировки. Стабильный алгоритм сортировки не меняет порядок записей с идентичными ключами (первый столбец в вашем случае).
Однако следует отметить, что более длинная расшифровка (с которой Ensembl и Havana согласны на 100%) дляENSDARG00000032737ген — ENSDART00000049291, который кодирует ENSDARP00000049290, а не ENSDARP00000120731. Но это не совсем мое дело.
решение3
Это идиоматическое решение будет надежно работать с любым awk в любой оболочке на любой машине UNIX:
$ awk '!seen[$1]++' file
ENSDARG00000032737 ENSDARP00000120731
ENSDARG00000061051 ENSDARP00000081062
решение4
Лучшие решения уже предоставлены, просто публикую свою попытку
for i in `awk '{if(!seen[$1]++)print $1}' filename`; do sed -n '/'$i'/{p;q}' filename; done
выход
ENSDARG00000032737 ENSDARP00000120731
ENSDARG00000061051 ENSDARP00000081062