私はRscriptを実行するbashスクリプトを生成するためにEOFを使用しています。 Rscriptはbasename
出力ファイル名を指定するために使用します。
bashスクリプトのリストを生成するために使用するときに機能さEOF
せることはできませんbasename
。エラーメッセージは以下の通りです。それでもbashスクリプトを生成できますが、${AF}
表示される2つの場所はすべて空白として表示されます。非常に奇妙な!
bashスクリプトをテストしましたが、動作しているので問題EOF
がありますbasename
。
basename
とどのように使用しますかEOF
?それとも代替がありますか?ありがとうございます。
for letter in {A..Z}
do cat <<- EOF > batch_${letter}.sh
#!/bin/bash
module load R/3.5.1
R_func="/home/dir/R_func"
TREAT="/home/dir/POP"
BASE="/home/dir/base"
OUTPUT="/home/dir/tmp"
for AF in ${BASE}/${letter}*.txt_step3; do
Rscript ${R_func}P_tools.R \
--ptool ${R_func}/P_tools_linux \
--group ${AF} \
--treat ${TREAT}/pop_exclude24dup \
--out ${OUTPUT}/OUT_$(basename ${AF%%_txt_step3})_noregress \
--binary-target F; done
EOF
done
エラーメッセージです。
basename:オペランドがありません。詳細については、「basename --help」を参照してください。
答え1
区切り文字を引用符で囲んでいない場合、コマンドの置き換え(たとえば、your$(basename ...)
や変数)もこの資料で拡張されます。あなたはその$
外だけ$(basename ...)
でなく、$
内側のすべてから逃げるべきです。
修正されたスクリプトバージョン:
for letter in {A..Z}
do cat <<- EOF > batch_${letter}.sh
#!/bin/bash
module load R/3.5.1
R_func="/home/dir/R_func"
TREAT="/home/dir/POP"
BASE="/home/dir/base"
OUTPUT="/home/dir/tmp"
for letter in {A..Z} do {
for AF in \${BASE}/${letter}*.txt_step3; do
Rscript \${R_func}P_tools.R \
--ptool \${R_func}/P_tools_linux \
--group \${AF} \
--treat \${TREAT}/pop_exclude24dup \
--out \${OUTPUT}/OUT_\$(basename \${AF%%_txt_step3})_noregress \
--binary-target F; done
}
EOF
done
これは実際にタブにインデントです。この愚かなWebインターフェイスは、タブを空白に切り替えて<<-
POSIXシェルの状況を破る可能性があります。ここでは、文書のスペースと行の前にあるEOF区切り文字ではなく、タブのみを削除します。
答え2
<< EOF
...ここでは、ドキュメントと呼ばれる構成がEOF
呼び出されます。必要な文字列を区切り文字として使用できますが、EOF
一般的です。
直面する問題は、ここで文書が二重引用符で囲まれた文字列のように動作するため、その中の変数とコマンドの置換が実行時に拡張され、cat
結果ファイルにそのまま保存されないことです。たとえば、R_func
作成中のスクリプトで設定しましたが、batch_x.sh
ビルドスクリプトの${R_func}
すべての値に拡張されるため、これはおそらく望むものではありません。R_func
here-doc区切り文字を引用してこれを防ぐことができます。つまりcat << 'EOF'
、。ただし、これにより拡張が防止されます。みんなしたがって、ファイルを部分的に生成しない場合、または引用符を持たない区切り文字を使用し、1つの変数を除くすべての変数をエスケープする場合は、次のような他の変数を拡張しないとファイルを拡張できません。ビリーおじさんの答え。
あなたの考えを正しく理解したら、26個のスクリプトを作成し、各文字をスクリプトの1つにハードコードする必要があります。生成した最初のスクリプト()はbatch_A.sh
次のとおりです。
module load R/3.5.1
R_func="/home/dir/R_func"
....
for AF in ${BASE}/A*.txt_step3; do
Rscript ${R_func}P_tools.R \
...
done
代わりに、以下のようにスクリプトを生成し、文字をコマンドライン引数として渡すことができます。最初のコマンドライン引数は次のように使用できます"$1"
。
#!/bin/bash
module load R/3.5.1
R_func="/home/dir/R_func"
TREAT="/home/dir/POP"
BASE="/home/dir/base"
OUTPUT="/home/dir/tmp"
letter=$1
for AF in ${BASE}/${letter}*.txt_step3; do
Rscript "${R_func}P_tools.R" \
--ptool "${R_func}/P_tools_linux" \
--group "${AF}" \
--treat "${TREAT}/pop_exclude24dup" \
--out "${OUTPUT}/OUT_$(basename "${AF%%_txt_step3}")_noregress" \
--binary-target F;
done
letter
これでコマンドラインから変数を取得できるので、ファイルなどをbatch.sh A
処理するために実行できます。A