部分文字列配列の作成方法

部分文字列配列の作成方法

文字列である変数シーケンスがあるとしましょう。

> sequence="AAAGCATATGCTAGCCCGTATAGCGATACTAGCTATACGATATATATGATCAATGCCCGTATAG"

各要素が初期シーケンスの3文字サブストリングであるseqのような配列を作成したいと思います。

echo $seq[1]
echo $seq[2]
echo $seq[n]

以下を提供します。

AAA  
GCA
TAG

ここで、nは配列の最後の要素です。誰かがこのためにスクリプトを書くことができますか?これは私がやろうとしているUnixコードとC ++コードの奇妙な組み合わせです。しかし、すべてUnixコードでなければなりません。

sequence="AAAGCATATGCTAGCCCGTATAGCGATACTAGCTATACGATATATATGATCAATGCCCGTATAG"
array_name=(seq) while($i+2<length(sequence)) {
seq[i]=substring(sequence,i,3)  i=i+3 }

答え1

以下でこれを行うとしましょうbash

sequence="AAAGCATATGCTAGCCCGTATAGCGATACTAGCTATACGATATATATGATCAATGCCCGTATAG"

for (( i = 0; i < ${#sequence}; i += 3 )); do
    printf '%s\n' "${sequence:i:3}"
done

これは一度に3つの塩基対ずつシーケンス長にわたって繰り返される。各反復ごとに、3つの塩基からなる次のセットを印刷します。

seq印刷する代わりに配列に入れるには、次の手順を実行します。

sequence="AAAGCATATGCTAGCCCGTATAGCGATACTAGCTATACGATATATATGATCAATGCCCGTATAG"

for (( i = 0; i < ${#sequence}; i += 3 )); do
    seq+=( "${sequence:i:3}" )
done

これはあなたに配列を提供しますseq。個々の配列要素は等として使用することができます"${seq[0]}""${seq[1]}"

残りの2つを取得するには読書ボックス、1、2から始まるようにループを変更します。

答え2

では、bashループとインデックスを使用して長い文字列を処理することができます。非常に速度が遅い。あるいは、read文字列を使用して配列を作成できます。

sequence="AAAGCATATGCTAGCCCGTATAGCGATACTAGCTATACGATATATATGATCAATGCCCGTATAG"

declare -a seq=( "" )
while read -n 3 -r triple ; do seq+=( "$triple" ); done <<< "$sequence"
declare -p seq

配列は空の文字列のインデックス0で作成されるため、必要に応じてインデックスが1から始まります。

これは、read -n 3""を使用して一度に3文字を変数として読み取って配列triple+=)に追加し、<<<リダイレクトを使用してシーケンスをレンダリングすることですstdinread入力が3の倍数でない場合を処理します。

(上記のエンコードと同様に、これは連続した文字シーケンスを読むのに適しています。これは、スペース、エスケープ文字、ヌルバイトなどを特に処理しないため、一般的な「分割」ルーチンではありませんIFS=""read入力からスペースを削除する必要がある場合に使用されます。... <<< ${sequence// /}

これはより一般的な問題の特別なケースです。 Bashで文字列を配列に分割する、不注意なプログラマーのすべての興味深いトラップについても読むことができます。 )

答え3

文字列にスペースや改行文字が含まれていない場合は、区切り文字grep列を使用して配列を作成できます。

sequence="AAAGCATATGCTAGCCCGTATAGCGATACTAGCTATACGATATATATGATCAATGCCCGTATAG"
seq=( $(printf '%s' "$sequence" | grep -o ... ) )

またはfold代わりに使用してくださいgrep

seq=( $(printf '%s' "$sequence" | fold -b3 ) )

と比較すると、grep最後の文字(G)も配列要素になります。


ノート:文字列にが含まれている場合、*問題が発生することがあります。たとえば、現在の作業ディレクトリにseq=( AT* ATA ATG )で始まるファイル名がある場合は、ファイル名に展開されます。これを使用してワイルドカードを防ぐATことができます。set -o noglob

より良い選択readarray代わりに使用seq=(...)

readarray seq < <(printf '%s' "$sequence" | fold -b3 )

(@Kusalanandaのクレジット)

関連情報