その行がない行セットを印刷します。

その行がない行セットを印刷します。

そのペアなしで2行セットを印刷しようとしています。結局この行を削除したいと思います。

例:

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を除くすべての位置で一致します。私はrn5とmm10の一致の前後のNMヘッダー番号である4行セットを維持したいと思います。したがって、上記の例では、rn5の1行目のヘッダーはmm10の3行目のヘッダーと一致するため保持されます。ただし、9行目のrn5ヘッダーは対応するペアではないため、次のようにヘッダーを印刷します。そして次の行の順序。私は最終的に同じ数のrn5とmm10エントリを含むファイルを持っていたいと思います。

私はUnixを初めて使用していますが、あなたの助けに心から感謝します。ありがとうございます。

予想される結果:

上記の項目のうち、対応する行はありません。この場合:

NM00125_rn5_0_1_4
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

答え1

これはawkのやや複雑なバージョンです。 Steeldriverのsedバージョンとのいくつかの違いは次のとおりです。

  1. mm10記録が記録される順序についてはrn5何もしません。
  2. rn5不足しているレコードを処理できます。
  3. 一致しないレコードをstderr
  4. 追加コードは次のようになります:-)

以下から実行できます。

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
}

また、このコードをファイルの末尾に追加して、一致しない行を次に出力することもできますstandard error

# 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

outfile要求された出力(標準出力を介して)をに出力し、残りの入力(標準エラーを介して)をに出力しますunmatched。さまざまな入出力リダイレクトの詳細については、次の章を参照してください。リダイレクトBashリファレンスマニュアルにあります。

答え2

考えるリクエストされた内容は

  • 4行のバッファを維持し、
  • 次の内容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

関連情報