ドキュメントのデフォルト名が競合していますか?

ドキュメントのデフォルト名が競合していますか?

私は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

関連情報