入力ファイルを処理して出力ファイルを生成するスクリプトがあります。各ファイルのデフォルト名を出力ファイルの一部にしたいのですが、うまくいきません。
while IFS= read -r line
do
tmp_header="tmp_header"
echo "Processing $line"
Sample_name=`basename -s .fastq.gz $line`
gsutil cat $line | zcat | awk 'BEGIN {FS = ":"} {lane=$4 ; print > "${Sample_name}.lane."lane".fastq.gz" ; for (i = 1; i <= 3; i++) {getline ; print > "${Sample_name}.lane."lane".fastq.gz"}}'
done < "test.list.paths.Bcancer2.txt"
$ cat test.list.paths.Bcancer2.txt
gs://fc-0e96c1b9-ba10-44f3-8b07-91a4c1a5cf14/10002/10002_R1.fastq.gz
結果ファイル
-rw-r--r-- 1 xkwaku001 2.2G Jul 8 05:54 '${Sample_name}.lane.2.fastq.gz'
しかし、私の結果は次のとおりです。
$ 10002_R1.lane.2.fastq.gz
ご協力ありがとうございます。
答え1
見た目に重要なように見える部分を切り取ると、次のようになります。
Sample_name=something
awk '{lane=$4 ; print > "${Sample_name}.lane."lane".fastq.gz"; ...}'
# ^ * * ^
Sample_name
また、awkがファイル名にシェル変数の値を使用したい場合があります。変数が一重引用符で囲まれた文字列内にあるため、シェルは変数を拡張しません。 (二重引用符で囲まれている場合、スクリプトは二重引用符とドル記号をエスケープする必要があります。)awkは、awkスクリプトの二重引用符で囲まれた文字列内にあるため、拡張しません(そしてawkではなくシェル構文です)。
したがって、これを行う最も簡単な方法は、シェル変数をawkに渡しawk -v
、今のようにawkスクリプトでそれを使用することですline
。単純化された例:
Sample_name=foobar
awk -v SN="$Sample_name" 'BEGIN {lane=123; print SN ".lane." lane ".fastq.gz" }'
実行すると印刷されますfoobar.lane.123.fastq.gz
。
答え2
あなたは使用していますシェルawkスクリプト内の変数ですが、$sample_name
awkはその変数にアクセスできません。さらに、引用されたので、awkはそれをユーザーが見る文字列として扱います。以下はスクリプトの作業バージョンです。
while IFS= read -r line
do
tmp_header="tmp_header"
echo "Processing $line"
Sample_name=$(basename -s .fastq.gz "$line")
gsutil cat "$line" | zcat |
awk -v sname="$Sample_name" '
BEGIN {FS = ":"}
{
lane=$4;
fileName = sname".lane."lane".fastq.gz"
print > fileName
for (i = 1; i <= 3; i++) {
getline
print > fileName
}
}'
done < test.list.paths.Bcancer2.txt
答え3
一重引用符を二重引用符に置き換えて、awkプログラムで引用符をエスケープすると、より幸せになると確信しています。 -Fを使用してawk実行のフィールド区切り文字を指定し、BEGINブロックにこれを設定する必要がないように入力することもできますcat $line | zcat ...
。zcat $line ...
猫の無駄な使用。
これが役立つことを願っています!