数値数量子としてsed - どのように?

数値数量子としてsed - どのように?

スラッシュとその後のすべての内容が削除されるように、複数のファイルの fasta ヘッダーを編集しようとします (「以降のすべての内容」が 10 文字以下の場合)。ヘッダー行は「>」と表示されます。

for i in ./*.fa;do sed -r 's/(>.*)\/.\{,10\}\n/\1\n/' "$i"; done

私も試しました

for i in ./*.fa;do sed -r 's/(>.*)\/.{,10}\n/\1\n/' "$i"; done

しかし、状況は良くなるシミが見えません。私の直感では、{,10}数量子がすべてを壊すということです。しかし、よくわかりません。助けてくれてありがとう!

たとえば、ファイルに次のものが含まれているとします。

>header1_some_extra_data_here/1-1000
ATGCGGGTACCCCA
>code/header2_some_extra_data
AGGTCCCCGGGAAAAA

出力が次のようになります。

>header1_some_extra_data_here
ATGCGGGTACCCCA
>code/header2_some_extra_data
AGGTCCCCGGGAAAAA

答え1

sed入力データで改行文字を一致させることができないため、交換は期待どおりに機能しません。これはsed、ファイルが1行ずつ読み取られるためです。つまり、改行を区切り文字として使用し、式は区切り線を使用せずに行に個別に適用されます。

代わりにコードを少し変更してください。

for fasta in ./*.fa; do
    sed 's;^\(>.*\)/.\{0,10\}$;\1;' "$fasta"
done

私が変更したものは次のとおりです。

  1. デフォルトではなくコマンド;の区切り文字として使用されます。これにより、私たちはパターンの問題から抜け出すことができなくなります。ほとんどすべての文字を区切り文字として使用できますが、パターンまたは代替テキストには表示されない文字を選択する必要があります。s/////
  2. 標準の基本正規表現構文を使用してください。パターンでは、(...)拡張正規表現構文はデフォルトの\{...\}正規表現構文です。移植性のために基本構文を使用することにしました。これはまた、-rGNUで拡張構文を有効にするオプションを放棄するという意味でもありますsed
  3. パターンを使用して線の始めと終わり^にそれぞれ固定します$
  4. 代替ビットに改行文字を挿入しようとしないでください。

sedそれを表現するもう一つの短い方法は次のとおりです。

sed '/^>/s;/.\{0,10\}$;;'

>これにより、その文字で始まるすべての行に置換が適用されます(/^>/後続のコマンドの「アドレス」として機能しますs///)。置換は単に/行末まで続くビットを削除します。もしこのビットの長さは10文字以下です。

答え2

以下は少し異なるアプローチです。

  1. 出力を新しいファイルに保存します。

    for file in *fa; do 
         sed -E 's|^\s*(>.{10,}.*)/.*|\1|' "$file" > "$file.fixed"; 
     done
    
  2. その場所でファイルを編集します。

    sed -i -E 's|^\s*(>.{10,}.*)/.*|\1|' *.fa 
    

この-Eオプションを使用すると、拡張正規表現を使用できます。これにより、()キャプチャと{}反復をエスケープせずに使用できます。わかりやすくするために、区切り文字をに変更して|追加しました^\s*(あなたのサポートがサポートされていない可能性があります。sedそうしないと、^ *時には前にスペースがある可能性があるため代わりに使用できます>)。これは時々fastaファイルにあるからです。

その後、秘密は、a>の後に10個以上の文字をaまで一致させ、/その文字を括弧で囲んで一致するようにキャプチャしてから、行全体を\1一致する部分に置き換えることです。

これにより、最長10文字を超えて最後の文字まで検索されます/。したがって、同じ行が複数ある場合、/最後の行を除くすべての行が保持されます。たとえば、

$ echo ">header1_some_extra_data_here/1-1000/foo/bar/baz" | 
    sed -E 's|^\s*(>.{10,}.*)/.*|\1|' 
>header1_some_extra_data_here/1-1000/foo/bar
    

これを防ぎ、最初の文字の後のすべての項目を削除するには/(10文字が一致する場合)、次のようにします。

sed -E 's|^\s*(>.{10}[^/]*)/.*|\1|'

関連情報