ファイルからデータを抽出し、内容を操作して新しいファイルに書き込みます。

ファイルからデータを抽出し、内容を操作して新しいファイルに書き込みます。

私に関連するデータを抽出するcsvファイルがあります。一方には参照番号があり、一方には文字G、A、T、Cの形の遺伝情報があります。

コンテンツCSV:

1,S188823,188823,,,,ACTCTCGA,,CTGTACCA,ID23,
1,S189843,189843,,,,ACCCTGGA,,CTTGTACA,ID23,
...

私に関連する情報は188823,,,,ACCCTGGA,,CTTGTACA すべての行から来ます。このプロセスでは、重複エントリを削除する必要があります。最初の2行も切り取る必要があります。

これが私が現在やっていることです:

cat File.csv | cut -d "," -f 3,9,7 | uniq | sed -e '1d' -e '2d'

結果は次のとおりです。

188823,ACTCTCGA,CTGTACCA
189843,ACCCTGGA,CTTGTACA
...

しかし、今やるべきことは2つありましたが、私は失敗しました。フィールド3とフィールド2を交換する必要があります。

188823,CTGTACCA,ACTCTCGA
189843,CTTGTACA,ACCCTGGA
...

フィールド2から始めて、塩基は「逆相補的」でなければなりません。つまり、すべての A が T になり、すべての C が G になり、すべての G が C になり、すべての T が A になり、シーケンスの順序が逆であるという意味です。したがってにCTGTACCAなりますTGGTACAG

最終結果は次のようになります。

188823,TGGTACAG,ACTCTCGA
188823,TGTACAAG,ACCCTGGA

これが理解できることを願って、私を助けることができることを願っています。リバースコンフィギュレーションのヘルプはここにあります。 オンラインRevCompジェネレータ

答え1

GNUの使用awk:

awk -F, '!seen[$3 FS $9 FS $7]++ {
    cmd="echo \047" $9 "\047 | rev | tr ATCG TAGC";
    if ((cmd |getline $9)>0){ print $3, $9, $7; };
    close(cmd);
}' OFS=, infile

出力:

188823,TGGTACAG,ACTCTCGA
189843,TGTACAAG,ACCCTGGA

NR>2コマンドに追加すると、awk 'NR>2{ ...; }'入力の最初の2行をスキップするように機能します。

ここでは[getlineパイプから変数への変換] cmd="..." $9 "..." (外部コマンドに関連する項目だけが二重引用符で囲まれています。)次に、パイプから呼び出してgetline同じフィールドに結果を保存し、$9結果getlineが成功すると出力に必須フィールドを印刷します。

最後に、閉鎖(ガイドライン)これ注文する我々は開いた。

!seen[$3 FS $9 FS $7]++処理フィールド#3、#9、#7の重複行を無視するために使用されます。

答え2

$ cat tst.awk
BEGIN {
    FS=OFS=","
    map["A"] = "T"
    map["C"] = "G"
    map["G"] = "C"
    map["T"] = "A"
}
{
    str = ""
    for (i=1; i<=length($9); i++) {
        str = map[substr($9,i,1)] str
    }
    print $3, str, $7
}

$ awk -f tst.awk content.csv
188823,TGGTACAG,ACTCTCGA
189843,TGTACAAG,ACCCTGGA

またはawkに関数をtr入力したい場合rev

$ cat tst.awk
BEGIN { FS=OFS="," }
{ print $3, rev(tr($9,"ACGT","TGCA")), $7 }

function tr(oldStr,oldChars,newChars,   i,pos,oldChar,newStr) {
    for (i=1; i<=length(oldStr); i++) {
        oldChar = substr(oldStr,i,1)
        pos     = index(oldChars,oldChar)
        newStr  = newStr (pos ? substr(newChars,pos,1) : oldChar)
    }
    return newStr
}

function rev(oldStr,    i,newStr) {
    for (i=1; i<=length(oldStr); i++) {
        newStr = substr(oldStr,i,1) newStr
    }
    return newStr
}

$ awk -f tst.awk content.csv
188823,TGGTACAG,ACTCTCGA
189843,TGTACAAG,ACCCTGGA

または両方を実行する関数:

$ cat tst.awk
BEGIN { FS=OFS="," }
{ print $3, trev($9,"ACGT","TGCA"), $7 }

function trev(oldStr,oldChars,newChars, i,pos,oldChar,newStr) {
    for (i=1; i<=length(oldStr); i++) {
        oldChar = substr(oldStr,i,1)
        pos     = index(oldChars,oldChar)
        newStr  = (pos ? substr(newChars,pos,1) : oldChar) newStr
    }
    return newStr
}

$ awk -f tst.awk content.csv
188823,TGGTACAG,ACTCTCGA
189843,TGTACAAG,ACCCTGGA

答え3

私たちはこれを使うことができますperl

  • 行をコンマに分割し、フィールドをゼロインデックス配列に保存します@F
  • リスト区切り記号$,とリスト結合子を$"コンマに設定します。
  • 9番目の要素の文字を反転し、$F[8]文字変換を適用します。
$ perl -F, -lane '
    BEGIN { $, = $" = ","; }
    print $F[2], reverse($F[8]) =~ tr/ATGC/TACG/r, $F[6]
      if $. > 2 && !$h{"@F[2,6,8]"}++;
' file
188823,TGGTACAG,ACTCTCGA
189843,TGTACAAG,ACCCTGGA

関連情報