一致する行の後の行のみを表示する方法は?

一致する行の後の行のみを表示する方法は?

ファイルがあります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]設定します。s2

    1. これから結果を印刷したいです。
    2. (最初は)印刷したい2行目(=フィールド)から始める初めて「タイトル」行を印刷したいからです。

    注可能な末尾のスペース/タブを防ぐために、$1 ~文字列比較全体の代わりに正規表現比較を使用しています。$1==

  • 設定されている場合は、snumberで始まるフィールド(=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. フィールド区切り文字を実際には不要なタブに設定します。
  2. 印刷を開始する必要があるときに注意してください
  3. まだ印刷していない場合は、次の行に進んでください。
  4. 次に始まる行を印刷しないでください。[
  5. スペースとタブでのみ定義された空白行をスキップします。
  6. ヘッダーの場合は、最初に表示したときに印刷してから、次の行に移動してください。
  7. 残りを印刷する

.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/最初と最後は、正規表現でアクセスできる範囲の境界ボックスです//。同様に、内部はを通じてアクセスすることができます//!。ただし、これが範囲を入力するときに使用する最初の正規表現です。

関連情報