ファイルがありますA.tsv
(フィールド区切り記号= \t
)。
for Research Use Only
[Header]
Test Name Il
Run ID 2102
Run Date 2021-02-04
Report Date/Time 2021-02-05 08:48
Instrument Serial
Flow Cell ID
Software Version
[Quality Control]
Lane 1,2,3,4 PASS
Lane 1,2,3,4 Index Set 1 PASS
[Patient Sample Results]
Sample ID Internal Control Result Consensus Sequence Lane Index Set Index ID
207 Pass Not Available 1,2,3,4 1 UDP0001
205 Pass Not Available 1,2,3,4 1 UDP0002
[Control Sample Results]
Sample ID Control Type Human Control SARS-CoV-2 Lane Index Set Index ID
CONTROL-POS Positive Control Not Detected Detected 1,2,3,4 1 UDP0008
新しいファイルに次の行を印刷したいと思います。
Sample ID Internal Control Result Consensus Sequence Lane Index Set Index ID
207 Pass Not Available 1,2,3,4 1 UDP0001
205 Pass Not Available 1,2,3,4 1 UDP0002
CONTROL-POS Positive Control Not Detected Detected 1,2,3,4 1 UDP0008
[Patient Sample Results]
だから、後ろの行を印刷したいのですが、[Control Sample Results]
ヘッダー行は一度だけ印刷したいと思います。
ファイルはサブサンプリングされ、行番号でハードコーディングすることはできません。
だから私は次のことを試しました。
awk '/Patient Sample Results/{getline; print}' A.tsv > data_info.tsv
ただし、最初のパターン以降の行だけを印刷します。私の問題に対する解決策はありますか?
答え1
セクション[ ... ]
この空行スペース/タブを含めることはできません。)、およびで始まるすべてのセクションの内容を印刷するには、[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
- これから結果を印刷したいです。
- (最初は)印刷したい2行目(=フィールド)から始める初めて「タイトル」行を印刷したいからです。
注可能な末尾のスペース/タブを防ぐために、
$1 ~
文字列比較全体の代わりに正規表現比較を使用しています。$1==
設定されている場合は、
s
numberで始まるフィールド(=line)を印刷しますs
(最初は2です)。次に、後で「ヘッダー」行をスキップできるように3に設定します。
フィールド(=行)は「現状のまま」印刷されるため、入力ファイル内の区切り文字は保持されます。
セクションが実際にスペースを含む「空白」行で区切られている場合、複数文字レコード区切り文字にGNUを要求する次の修正を使用すると、awk
これは発生しません(参照:StackOverflowに対する@EdMortonの返信例えば):
awk -F'\n' -v RS='\n(([[:space:]]*\n)+|$)' ' ... '
これは、「完全に空白または空白文字のみを含む」数値をレコード区切り文字として扱います。
答え2
たぶん良い
awk 'BEGIN {FS="\t"}
/^\[Patient Sample Results]/ { printing=1 ; next }
!printing { next }
/^\[/ { next }
/^[ \t]*$/ { next }
/^Sample/ { if (!printedheader) { print }; printedheader=1 ; next }
{ print }'
- フィールド区切り文字を実際には不要なタブに設定します。
- 印刷を開始する必要があるときに注意してください
- まだ印刷していない場合は、次の行に進んでください。
- 次に始まる行を印刷しないでください。
[
- スペースとタブでのみ定義された空白行をスキップします。
- ヘッダーの場合は、最初に表示したときに印刷してから、次の行に移動してください。
- 残りを印刷する
.1
{ print }
編集する。コメントに応じて空行の定義が変更されました。
答え3
努力する:
awk '/\[(Patient|Control) Sample Results\]/{ hdr++; next }
hdr==2 { hdr--; next }
hdr && !rep { print; rep=1; next }
rep && $0!="" { print }
' infile
答え4
これを使用して、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/
最初と最後は、正規表現でアクセスできる範囲の境界ボックスです//
。同様に、内部はを通じてアクセスすることができます//!
。ただし、これが範囲を入力するときに使用する最初の正規表現です。