8

私はシェルスクリプトの初心者で、「for」コマンドの実行方法を理解するのに一日中苦労しています。基本的に、私がやろうとしていることは次のとおりです。

私はたくさんの名前を持つ list.txt ファイルを持っています:

name1
name2
name3

リスト内のすべての名前に対して、2 つの異なるファイルがあり、それぞれ名前の末尾が異なります。元:

name1_R1
name1_R2

実行しようとしているプログラムはsickle. 基本的に、(互いに対応する) 2 つのファイルを取得し、それらに対して分析を実行するため、この命名規則を使用する必要があります。鎌のコマンドは次のとおりです。

sickle pe -f input_file1.fastq -r input_file2.fastq -t sanger \

誰かが私を助けてくれれば、少なくとも unix にファイルのリストを読み取らせ、各行を個別に処理させる方法を教えてもらえれば、そこから行くことができると思います。いくつか試してみましたが、どれもうまくいきませんでした。

4

3 に答える 3

16

いくつかの方法があります。データ ファイルの名前は「1 行に 1 つ」であるため、ファイル名に改行が含まれていないと想定できます。

forループ

for file in $(<list.txt)
do
    sickle pe -f "${file}_file1.fastq" -r "${file}_file2.fastq" -t sanger
done

whileでループread

while read file
do
    sickle pe -f "${file}_file1.fastq" -r "${file}_file2.fastq" -t sanger
done < list.txt

ループはfor、名前に空白が含まれていない場合 (タブなどの他の空白文字も含まれていない場合) にのみ機能します。while名前に改行が含まれていない限り、ループはきれいですが、を使用するwhile read -r fileと、予期しない事態に対する保護がさらに強化されます。ループ内のファイル名を囲む二重引用符は、ファイル名にfor空白を含めることができないため装飾的 (ただし無害) ですが、ループ内の二重引用符は、空白whileを含むファイル名が分割されるべきではない場合に分割されるのを防ぎます。多くの場合、変数を使用するたびにクォートすることをお勧めしますが、厳密には、変数に空白が含まれている可能性があるが、値を分割したくない場合にのみ重要です。

あなたの質問はそれについて明確ではないので、どの名前をsickleコマンドに渡す必要があるかを推測する必要がありました — 私は間違って推測したと99%確信していますが、ベース名を仮定すると、サンプルコマンドのさまざまなサフィックスと一致しますファイルはinput。末尾のバックスラッシュは省略しました。それは「エスケープ」文字であり、実際に何が必要かは明確ではありません。

于 2013-08-03T02:39:57.507 に答える
4

Bash の For ループを使用する

Bash には、そのループ構造の 1 つとして非常に妥当な for ループがあります。以下の echo コマンドは、必要なカスタム コマンドに置き換えることができます。例えば:

for file in name1 name2 name3; do
  echo "${file}_R1" "${file}_R2"
done

アイデアは、ループが各ファイル名をファイル変数に割り当ててから、それらに _R1 および _R2 サフィックスを追加するというものです。引用は重要な場合があり、必要がなければ害はないので、防御的なプログラミング手段として使用する必要があることに注意してください。

引数リストにxargsを使用する

for ループを直接使用する代わりにファイルから読み取りたい場合は、Bash のread builtinを使用できますが、多くの場合、シェル間でxargsの方が移植性が高くなります。たとえば、次の例では、GNU findutilsのxargsのバージョンで使用可能なフラグを使用して、ファイルから引数を読み取り、それぞれに接尾辞を追加します。

$ xargs --arg-file=list.txt --max-args=1 -I{} /bin/echo "{}_R1" "{}_R2"
name1_R1 name1_R2
name2_R1 name2_R2
name3_R1 name3_R2

ここでも、「echo」を任意のコマンド ラインに置き換えることができます。

于 2013-08-03T02:36:44.370 に答える
3

while次のループを使用しreadます。

while read fn; do
    <command> "${fn}_R1" "${fn}_R2"
done < list.txt
于 2013-08-03T02:30:19.937 に答える