Вы можете использовать NR и FNR в awk.
awk 'FNR==NR { _a[FNR]=$3;} NR!=FNR { $4 += _a[FNR]; print; }' file1 file2
Не совсем тот порядок сортировки, который вы показали, но, может быть, тоже верно?
$ 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}}'
С GNU sort
и при условии, что строки не содержат символов TAB:
paste - - < file | sort -V | tr '\t' '\n' | awk '!seen[$0]++'
Или sort -t$'\t' -sk1,1V
, чтобы сохранить исходный порядок записей с идентичными нечетными строками, как в ожидаемом результате.
Если у вас нет GNU sort
и предполагается, что нечетные строки всегда следуют этому шаблону, вы можете заменить sort -V
на sort -k1.9n
.
Чистый 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 не предлагает возможность естественной сортировки, также известной как сортировка версии(по тексту с номерами ).
Предварительная -и постобработка с помощью 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 -
for element in $(sed -n 'p;n' a.txt |sort -nk 1.9 |uniq |awk '{print $1}')
do
echo $element; cat a.txt |grep -A1 $i |grep -v trans |grep -v \\\\--
done
Где.txt — ваш ввод. Проверено:
[root@megatron ~]# cat a.txt
transcr_25793 +
YAL039C -
transcr_25793 +
YAL037C-B -
transcr_20649 +
YBL100C -
transcr_7135 +
YBL029C-A -
transcr_11317 +
YBL067C -
transcr_25793 +
YAL038W +
transcr_7135 +
YBL029W +
[root@megatron ~]# for i in $(sed -n 'p;n' a.txt |sort -nk 1.9 |uniq |awk '{print $1}')
do
echo $i; cat a.txt |grep -A1 $i |grep -v trans |grep -v \\\\--
done
transcr_7135
YBL029C-A -
YBL029W +
transcr_11317
YBL067C -
transcr_20649
YBL100C -
transcr_25793
YAL039C -
YAL037C-B -
YAL038W +
[root@megatron ~]#
Позвольте мне еще раз сформулировать вашу проблему. Вы действительно хотите сделать две операции:
transcr*
)строки по номеру в строке, сохраняя четные -пронумерованные(Y*
)строки, связанные с предыдущей строкой Y*
строки, подпадающие под одинаковые transcr*
строки Хотя я восхищаюсь однострочными решениями -в других ответах, я думаю, что это достаточно сложно, чтобы написание сценария могло быть оправдано. Кроме того, после сохранения сценария в файле его можно повторно использовать и улучшать по мере изменения ваших потребностей.
Этот скрипт примет ваш ввод и создаст строки, идентичные вашему окончательному выводу:
#!/bin/env python
from collections import defaultdict
import fileinput
import re
def pair_lines (iterable):
''' Return lines two at a time '''
args = [iterable] * 2;
return zip(*args)
dd = defaultdict(list)
for line1,line2 in pair_lines(fileinput.input()):
# accumulate lists of all second lines that share the same first
# line value
dd[line1].append(line2)
def line_index (line):
''' Return first substring that looks like an integer '''
return int(re.search(r'\d+',line).group(0))
# sort by first lines and print results
for line1 in sorted(dd.keys(), key=line_index):
print(line1, *dd[line1], end='', sep='')
Выполнить с помощью:
reorder.py input.txt > output.txt