Я пытаюсь напечатать набор из двух строк, которым нет соответствующей пары. В конечном итоге я хочу удалить эти строки.
NM00123_rn5_0_1_2
XXXXXXXXXXXXXXXXXXXXXXXXXXX
NM00123_mm10_0_1_2
XXXXXXXXXXXXXXXXXXXXXXXXXXXX
NM00124_rn5_0_1_3
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
NM00124_mm10_0_1_3
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
NM00125_rn5_0_1_4
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
NM00126_rn5_0_1_5
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRr
NM00126_mm10_0_1_5
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
Строка, начинающаяся с NM, - это заголовки, а следующая строка состоит из последовательности алфавитов. Строки заголовка для пары совпадают во всех позициях, кроме rn5 и mm10. Я хочу сохранить только наборы из четырех строк, в которых цифры заголовка NM до и после rn5 и mm10 совпадают для пары. Итак, из приведенного выше примера: Заголовок в строке 1 для rn5 совпадает с заголовком в строке 3 для mm10, так что оставьте это .... но заголовок для rn5 в строке 9 не имеет соответствующей пары, поэтому выведите и заголовок, и следующую строку с последовательность. Я хочу, наконец, иметь файл с равным количеством записей rn5 и mm10.
Я новичок в использовании Unix и был бы очень признателен за помощь в этом. Спасибо.
Все приведенные выше записи без строки без соответствующей пары. В данном случае:
NM00125_rn5_0_1_4
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
Вот несколько запутанная версия для awk. Некоторые отличия от версии sed от steeldriver:
mm10
или rn5
rn5
record stderr
. Его можно запустить с помощью:
awk -f my_program.awk infile
Код:
# find and store a header
/^NM.*/ { header = $0; next }
# we found an mm10 line
header ~ /_rn5/ {
# get the mm10 line that matches this rn5
mm_match = header
sub("_rn5", "_mm10", mm_match)
# if we have a previous mm10, then print the pair
if (mm_match in headers) {
print header
print
print mm_match
print headers[mm_match]
delete headers[mm_match]
} else {
headers[header] = $0
}
next
}
# we found an mm10 line
header ~ /_mm10/ {
# get the rn5 line that matches this mm10
mm_match = header
sub("_mm10", "_rn5", mm_match)
# if we have a previous rn5, then print the pair
if (mm_match in headers) {
print mm_match
print headers[mm_match]
print header
print
delete headers[mm_match]
} else {
headers[header] = $0
}
next
}
Кроме того, этот код можно добавить в конец файла для вывода любых несовпадающих строк в стандартная ошибка
:
# The END block is here just to output anything that was unmatched
END {
# dump the unmatched to stderr
for (header in headers) {
print header > "/dev/stderr"
print headers[header] > "/dev/stderr"
}
}
Его можно запустить с помощью:
awk -f my_program.awk infile > outfile 2> unmatched
Которая будет выводить запрошенный вывод (через стандартный вывод) в файл вывода
, и выводит оставшийся ввод (через стандартную ошибку) в несравнимо
. Подробные сведения о перенаправлении ввода-вывода во всем его разнообразии см. В главе о Перенаправления в справочном руководстве Bash.
Я думаю то, о чем вы просите, - это что-то что
rn5
(до следующей новой строки), совпадает с тем, что следует за mm10
(до следующей, кроме двух, новой строки), напечатайте это и начните заново Это, вероятно, уродливый способ сделать это, но для иллюстрации с помощью GNU sed
:
$ sed -n -e :a \
-e '$!N; /rn5_\(.*\)\n.*\n.*mm10_\1\n/ {p;b}' \
-e '/.*\n.*\n.*\n/ D' \
-e ba infile > outfile
$ diff outfile infile
8a9,10
> NM00125_rn5_0_1_4
> zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz