Может быть, что-то вроде
awk 'BEGIN {FS="\t"}
/^\[Patient Sample Results]/ { printing=1 ; next }
!printing { next }
/^\[/ { next }
/^[ \t]*$/ { next }
/^Sample/ { if (!printedheader) { print }; printedheader=1 ; next }
{ print }'
[
Написано, чтобы быть как можно более очевидным, вместо того, чтобы использовать идиомы awk, такие как 1
вместо { print }
.
Правка. Измените определение пустой строки в ответ на комментарий.
Предполагая, что ваши разделы [... ]
разделены пустыми строками (, которые не должны содержать пробелы/табуляции ), и вы хотите напечатать содержимое всех разделов, начинающихся с [Patient Sample Results]
, следующее должно работать:
awk -F"\n" -v RS="" '$1~/^\[Patient Sample Results\]/{s=2}
s{for (i=s;i<=NF;i++) print $i; s=3}' A.tsv > data_info.tsv
Это даст указание awk
работать в «режиме абзаца», рассматривая любую группу пустых строк как разделитель записей, а новую строку как разделитель полей.
«Названия разделов» теперь будут отображаться как первое «поле»($1
)ваших записей.
Как только первое поле (= строка )или запись начинается с [Patient Sample Results]
, мы устанавливаем флаг s
на 2
, чтобы указать
Примечание. Я использовал сравнение регулярных выражений $1 ~
вместо полного сравнения строк $1==
для защиты от возможного пробела/табуляции в конце.
Если установлено s
, выведите поля (=lines ), начиная с номера s
, который изначально будет равен 2. Затем установите его на 3, чтобы мы пропустили строку «заголовок» в будущее.
Поскольку поля (=строки )печатаются "как есть", это сохранит символ-разделитель, найденный во входном файле.
Если ваши разделы разделены «пустыми» строками, которые на самом деле содержат пробелы , следующая модификация, которая требует GNU awk
для многосимвольных разделителей записей -, защитит от этого (, см. . ] Ответ @EdMorton на StackOverflow , например):
awk -F'\n' -v RS='\n(([[:space:]]*\n)+|$)' '... '
Это сделает любое количество «полностью пустых строк или содержащих только пробельные символы» в качестве разделителя записи.
Попробуйте:
awk '/\[(Patient|Control) Sample Results\]/{ hdr++; next }
hdr==2 { hdr--; next }
hdr && !rep { print; rep=1; next }
rep && $0!="" { print }
' infile
Используя GNU sed
, мы можем сделать следующее, и порядок не будет иметь значения, перечислены ли в файле конфигурации A.tsv результаты пациента или контрольного образца
sed -En '
/\[(Patient|Control) Sample Results]/,/^\s*$/{
//!{p;d;}
/\S/!d;n;G
/\n./n;P;h
}
' A.tsv
Некоторая терминология :в диапазоне строк /begin/,/end/
первая и последняя являются ограничивающими рамками диапазона и доступны через регулярное выражение //
. Точно так же внутренние помещения доступны через //!
. При условии, что это первое регулярное выражение, которое мы используем при вводе диапазона.