Как отсортировать по нечетным строкам, а затем удалить повторяющиеся значения?

Как отсортировать по нечетным строкам, а затем удалить повторяющиеся значения?

У меня есть файл следующего типа:

transcr_25793 +
YAL039C -
transcr_25793 +
YAL037C-B -
transcr_20649 +
YBL100C -
transcr_7135 +
YBL029C-A -
transcr_11317 +
YBL067C -
transcr_25793 +
YAL038W +
transcr_7135 +
YBL029W +

Я пытался получить что-то вроде этого:

transcr_7135 +
YBL029C-A -
transcr_7135 +
YBL029W +
transcr_11317 +
YBL067C -
transcr_20649 +
YBL100C -
transcr_25793 +
YAL039C -
transcr_25793 +
YAL037C-B -
transcr_25793 +
YAL038W +

Затем, после этого, я искал что-то вроде этого:

transcr_7135 +
YBL029C-A -
YBL029W +
transcr_11317 +
YBL067C -
transcr_20649 +
YBL100C -
transcr_25793 +
YAL039C -
YAL037C-B -
YAL038W +

Я пролистал sortруководство и некоторые посты, но не смог найти ничего подходящего, просто sortиспользую числовые значения для получения нечетных строк...

решение1

Чистый gawkраствор:

awk -F_ 'NR%2{i=$2;next}{a[i]=a[i]"\n"$0}
         END{PROCINFO["sorted_in"]="@ind_num_asc";
             for(i in a) printf "%s","transcr_"i""a[i]"\n"}' file

Хитрость заключается в том, чтобы отсортировать индексы массива aчисленно с небольшой помощью gawkспециального массива PROCINFO.

transcr_7135
YBL029C-A -
YBL029W +
transcr_11317
YBL067C -
transcr_20649
YBL100C -
transcr_25793
YAL039C -
YAL037C-B -
YAL038W +

Кстати, жаль, что awk не предлагает возможности сортировки естественным образом, т.е.сортировка версии(по тексту с номерами).

решение2

Не совсем тот порядок сортировки, который вы показали, но, возможно, это верно?

$ cat input.txt|paste - -| sort -k1,1V -k2,2| tr "\t" "\n" | awk '{if($0 in line == 0) {line[$0]; print}}'
    transcr_7135 +
    YBL029C-A -
    YBL029W +
    transcr_11317 +
    YBL067C -
    transcr_20649 +
    YBL100C -
    transcr_25793 +
    YAL037C-B -
    YAL038W +
    YAL039C -

РЕДАКТИРОВАТЬ:

Вставьте номер строки и используйте его в качестве ключа сортировки, это должно дать именно тот результат, который вам нужен:

$ cat input.txt | paste - - | nl | sort -k2,2V -k1,1g | cut -f2- | tr "\t" "\n" | awk '{if($0 in line == 0) {line[$0]; print}}'

решение3

С GNU sortи при условии, что строки не содержат символов табуляции:

paste - - < file | sort -V | tr '\t' '\n' | awk '!seen[$0]++'

Или sort -t$'\t' -sk1,1Vсохранить исходный порядок записей с идентичными нечетными строками, как в ожидаемом вами выводе.

Если у вас нет GNU sortи предполагается, что нечетные строки всегда следуют этому шаблону, вы можете заменить sort -Vих на sort -k1.9n.

решение4

Предварительная и постобработка с помощью awk; это не предполагает, что transcrза строкой следует только одна Y*строка; это также идемпотентно — ее вывод может быть передан обратно в качестве ввода, и это даст тот же результат.

awk '{print $0~/^transcr/ ? t=$0 : t" "$0}' /tmp/foo | sort -t_ -k2n -k2 -u | awk '{print (NF > 2) ? $3" "$4 : $0}'
transcr_7135 +
YBL029C-A -
YBL029W +
transcr_11317 +
YBL067C -
transcr_20649 +
YBL100C -
transcr_25793 +
YAL037C-B -
YAL038W +
YAL039C -

Связанный контент