私はパンゲノムパイプラインを実行しており、roary
forループ内にスクリプトを書く必要があります。たとえば、次gff
のようなファイルがあります。
a.gff
b.gff
5.gff
101.gff
clustered_proteins
roary
以下のように、パイプラインから固有の遺伝子を検索するコマンドを実行する必要があります。
query_pan_genome -a difference --input_set_one a.gff --input_set_two b.gff,5.gff,101.gff -g clustered_proteins
query_pan_genome -a difference --input_set_one b.gff --input_set_two a.gff,5.gff,101.gff -g clustered_proteins
query_pan_genome -a difference --input_set_one 5.gff --input_set_two a.gff,b.gff,101.gff -g clustered_proteins
query_pan_genome -a difference --input_set_one 101.gff --input_set_two a.gff,b.gff,5.gff -g clustered_proteins
同じことを行うために、以下のようにスクリプトを作成しました。
file1=*.gff
file2=*.gff
file3="-f "$file1-$file2"
for file in *.gff
do
query_pan_genome -a difference --input_set_one "$file1" --input_set_two "$file3" -g clustered_proteins
done
しかし、上記のスクリプトは私の目的には合いません。スクリプトが非常にシンプルで書くのが難しいことだけを知っています。スクリプトを改善するのに役立ちます。
よろしくお願いします。
答え1
使用/bin/sh
:
#!/bin/sh
set -- *.gff
for name do
shift
( IFS=,
query_pan_genome -a difference \
--input_set_one "$name" \
--input_set_two "$*" \
-g clustered_proteins
)
set -- "$@" "$name"
done
まず、位置引数をパターンに一致するファイル名のリストに設定します*.gff
。次にリストを繰り返して、変数をname
現在のファイル名の値に設定します。
ループ内では、各ファイル名に対して、最初の位置引数が位置引数リストから削除されます。移動された要素は、江戸の現在のファイル名に対応します$name
。それ以降は、shift
位置引数リストに他のファイル名が含まれますが、含まれません$name
。
(...)
ループのサブシェルでローカルIFS
にコンマに設定しました。つまり、"$*"
カンマで区切られた現在位置引数のリストで構成される文字列に展開されます。
次に、ファイル名と他のファイル名をカンマ区切りリストとしてquery_pan_genome
使用して$name
ユーティリティを呼び出します。
サブシェルの後、ループ本体が終了する直前に現在の名前が位置引数リストに戻りますが、最後にあります。
リストを繰り返しても、ループ内の位置引数のリストを変更することに問題はありません。私たちが繰り返すリストは、ループ内でおよびを使用して変更されたshift
リストの変更不可能なコピーですset
(for
ループは常に静的要素のリストを繰り返します)。
問題のGFFファイルのリストが与えられた場合、上記のコードは最終的に次の4つのコマンドを実行します。
query_pan_genome -a difference --input_set_one 101.gff --input_set_two 5.gff,a.gff,b.gff -g clustered_proteins
query_pan_genome -a difference --input_set_one 5.gff --input_set_two a.gff,b.gff,101.gff -g clustered_proteins
query_pan_genome -a difference --input_set_one a.gff --input_set_two b.gff,101.gff,5.gff -g clustered_proteins
query_pan_genome -a difference --input_set_one b.gff --input_set_two 101.gff,5.gff,a.gff -g clustered_proteins
答え2
以下を使用する方が簡単ですzsh
。
#! /bin/zsh -
files=(*.gff(N))
# don't run that command if there are fewer than 2 files
(( $#files < 2 )) ||
for f ($files)
query_pan_genome -a difference \
--input_set_one $f \
--input_set_two ${(j[,])files:#$f} \
-g clustered_proteins
どこ
${array:#pattern}
パターンと一致しない配列の要素に拡張されるため、ここではExceptが使用されます${files#$f}
。$files
$f
${(j[,])array}
配列の要素を に連結します,
。
代わりに、glob拡張オプションを持つglob修飾子を*.gff(N)
使用してglobを有効にできます。*.gff(Nn)
n
numericglobsort
file10.gff
後ろに file2.gff
例えば。
答え3
配列を使用してそのインデックスを繰り返し、各インデックスを一時的に設定解除できます。
#! /bin/bash
input_files=(*.gff)
IFS=,
for index in "${!input_files[@]}"
do
input_file=${input_files[$index]}
unset input_files[$index]
echo "$input_file" "${input_files[*]}"
input_files[$index]=$input_file
done
出力例:
101.gff 5.gff,a.gff,b.gff
5.gff 101.gff,a.gff,b.gff
a.gff 101.gff,5.gff,b.gff
b.gff 101.gff,5.gff,a.gff