sed while ループエラー

sed while ループエラー

解析するファイルがあります。

mmu-miR-15-5p/16-5p/195-5p/424-5p/497-5p    0610007P14Rik
mmu-miR-326-3p/330-5p   0610007P14Rik
mmu-miR-326-3p/330-5p   Lmir
mmu-miR-15/16/195/424/497   0610007P14Rik
mmu-miR-15-5p/16-5p/195-5p/424-5p/497-5p/6838-5p    0610007P14Rik
mmu-miR-15/16/195/424-5p/497    Alinf
mmu-miR-326/330-5p  0610007P14Rik
mmu-miR-326/330 0610007P14Rik
mmu-miR-1/206/613   Crgi
mmu-miR-1-3p/206    0610007P14Rik

希望の出力:

最初の行の場合

mmu-miR-15-5p   0610007P14Rik
mmu-miR16-5p    0610007P14Rik
mmu-miR195-5p   0610007P14Rik
mmu-miR424-5p   0610007P14Rik
mmu-miR497-5p   0610007P14Rik

など...

2番目の列と新しい行を置き換えて/作成するだけです。mmu-miR

Bashで次のコード行を試しました。

sed 's/\//\nmmu-miR/g' test.txt

mmu-miR-15-5p
mmu-miR16-5p
mmu-miR195-5p
mmu-miR424-5p
mmu-miR497-5p   0610007P14Rik
mmu-miR-326-3p
mmu-miR330-5p   0610007P14Rik
mmu-miR-326-3p
mmu-miR330-5p   Lmir

whileループと次のsedコマンドを試しました。

while read line; do 
    lineCols=( $line ); 
    v1=($(echo "${lineCols[0]}"));
    v2=($(echo "${lineCols[1]}"));
    sed 's/\//\n/g' ${v1};
done <test.txt

しかし、エラーが発生しました。

sed: can't read mmu-miR-15-5p/16-5p/195-5p/424-5p/497-5p: No such file or directory
sed: can't read mmu-miR-326-3p/330-5p: No such file or directory
sed: can't read mmu-miR-326-3p/330-5p: No such file or directory
sed: can't read mmu-miR-15/16/195/424/497: No such file or directory
sed: can't read mmu-miR-15-5p/16-5p/195-5p/424-5p/497-5p/6838-5p: No such file or directory

私は何が間違っていましたか?

答え1

この目標を達成する方法awk

より良い読みやすさ/使いやすさのために、以下を含むawkスクリプト()を生成します。myScript.awk

{ 
  n=split($1, a, "/")
  split(a[1], b, "-")

  for (i=1; i<n+1; i++) {
    if (i == 1) {
      printf a[i]"\t"$2"\n"
    }
    else {
      printf b[1]"-"b[2]"-"a[i]"\t"$2"\n"
    }    
  }
}

仕組み:

n=split($1, a, "/")

この行は最初の行を取ります。大地(例:"mmu-miR-15-5p/16-5p/195-5p/424-5p/497-5p"最初の行)区切り文字「/」で分割して配列に保存しa、分割要素の数をに保存しますn。最初の行の場合:

a[1] = "mmu-miR-15-5p"
a[2] = "16-5p"
a[3] = "195-5p"
a[4] = "424-5p"
a[5] = "497-5p"
n = 5

コマンドはawk各行で実行されるため、次の行の結果は異なります。

split(a[1], b, "-")

同様に、この行は最初の要素を取得し、区切りa文字「-」で区切ります。これは以下を生成します。

b[1] = "mmu"
b[2] = "miR"
b[3] = "15"
b[4] = "5p"

aこのような配列があれば、出力行数(入力行で「/」で区切られた要素数)を繰り返し、配列ビットと!を使用して各行を設定するだけですb。最初の行にはa[1]「mmu-miR-」がすでに含まれているため、例外を作成する必要があるため、ifこの場合を区別してください。

それを実行する方法

awk -f myScript.awk input.txt

テストした結果、質問から要求された内容が出力されました。

ノート あなたの質問に対する私の意見で述べたように、単一の呼び出しをawk使用することは、ファイルの各行を繰り返すよりも効率的で「シェルに優しい」です。

編集者ノート あなたのコメントに基づいてスクリプトを修正しました。今大丈夫だと思います!

答え2

私はあなたが次のようなものを探していると思います。

cat inputFile.txt | while read line
    do
        eval `echo "$line" | sed 's|^\([^/]*\)/\([^ ]*\) \(.*\)|name="\1" ports=\2 tag="\3"|'`
        echo "$name $tag"
        realname=`echo "$name" | sed 's|-[0-9].*||'`
        for port in $(echo $ports | sed 's|/| |g')
        do
            echo "$realname-$port $tag"
            #or echo "$realname$port $tag", but I suspect a typo in your initial post
        done
    done

答え3

入力がヘッダーなしのTSVファイル(つまり、ヘッダー行なしでタブ区切りファイル)であると仮定すると、次のように読み取ることができます。ミラーmlr)および「入れ子になっていない」各レコードは、/最初のフィールドに-で区切られた文字列で構成されています。その後、その文字列mmu-miR-がまだ含まれていない最初のフィールドのすべての値にその文字列を追加できます。

$ mlr --tsv -N nest --evar '/' -f 1 then put -S '$1 !=~ "^mmu-miR-" { $1 = "mmu-miR-" . $1 }' file
mmu-miR-15-5p   0610007P14Rik
mmu-miR-16-5p   0610007P14Rik
mmu-miR-195-5p  0610007P14Rik
mmu-miR-424-5p  0610007P14Rik
mmu-miR-497-5p  0610007P14Rik
mmu-miR-326-3p  0610007P14Rik
mmu-miR-330-5p  0610007P14Rik
mmu-miR-326-3p  Lmir
mmu-miR-330-5p  Lmir
mmu-miR-15      0610007P14Rik
mmu-miR-16      0610007P14Rik
mmu-miR-195     0610007P14Rik
mmu-miR-424     0610007P14Rik
mmu-miR-497     0610007P14Rik
mmu-miR-15-5p   0610007P14Rik
mmu-miR-16-5p   0610007P14Rik
mmu-miR-195-5p  0610007P14Rik
mmu-miR-424-5p  0610007P14Rik
mmu-miR-497-5p  0610007P14Rik
mmu-miR-6838-5p 0610007P14Rik
mmu-miR-15      Alinf
mmu-miR-16      Alinf
mmu-miR-195     Alinf
mmu-miR-424-5p  Alinf
mmu-miR-497     Alinf
mmu-miR-326     0610007P14Rik
mmu-miR-330-5p  0610007P14Rik
mmu-miR-326     0610007P14Rik
mmu-miR-330     0610007P14Rik
mmu-miR-1       Crgi
mmu-miR-206     Crgi
mmu-miR-613     Crgi
mmu-miR-1-3p    0610007P14Rik
mmu-miR-206     0610007P14Rik

ここで、最初のMillerサブコマンドは、nestスラッシュ内の最初のフィールドを分割し、別のフィールド(この場合はもう1つのフィールドのみ)をもう一度コピーしてレコードを「ネスト解除」または「爆発」するために使用されます。生成された各文字列の追加ロギング。

2番目のMillerサブコマンドは、put結果の最初のフィールド値が正しいプレフィックス文字列で始まるかどうかをテストし、そうでない場合はそれを追加します。オプションは、Millerがフィールドの種類を推論するのを-S防ぎput、すべてのフィールドを次のように処理します。テキスト


質問への入力を考慮すると、awk次のような結果が得られます。

awk -F '\t' '
    BEGIN { OFS=FS }
    {
        nf = split($1,a,"/")
        
        print a[1], $2
        for (i = 2; i <= nf; ++i)
            print "mmu-miR-" a[i], $2
    }' file

また、ファイルをタブ区切りのファイルとして読み込み、最初のフィールドをスラッシュに分割して配列に新しい文字列セットを作成しますa。次に、最初の生成された文字列と2番目のフィールドを印刷してから、生成された残りの文字列を繰り返して、各文字列の前に足りないmmu-miR-プレフィックスを追加し、2番目のフィールドの値を使用して出力します。

関連情報