
HPCクラスタを使用してかなり大きな(〜3GB)ファイルバッチをダウンロードするために、複数の「wget」シェルスクリプトを作成したいと思います。ファイル名は次のように filenames.txt に保存されます。
$cat filenames.txt
file1
file2
file3
...
私が取得したいURLは次のように構成されています。
ftp://host.com/dir1/dir2/file1/file1.sra
ftp://host.com/dir1/dir2/file2/file2.sra
ftp://host.com/dir1/dir2/file3/file3.sra
各wgetのシェルスクリプトを生成し、それを変数自体というファイルに書きたいと思います。たとえば、file1.sh には以下を含める必要があります。
#!/bin/bash
wget ftp://host.com/dir1/dir2/file1/file1.sra
そして、file2.shには次のものを含める必要があります。
#!/bin/bash
wget ftp://host.com/dir1/dir2/file2/file2.sra
ご覧のとおり、一致するパターンは、1)URLと2)作成するファイル名です。ファイル名にURLを「追加」してから、その名前を付けた.shファイルに書き込むにはどうすればよいですか?
答え1
これを行うには、非常に単純なシェルループを作成できます。
while read filename
do
echo '#!/bin/bash' > $filename.sh
echo "wget ftp://host.com/dir1/dir2/$filename/$filename.sra" >> $filename.sh
done < filenames.txt
これは各行を読み取り、filenames.txt
呼び出してから、各行に置き換えられたファイルの行に名前が付けられたfilename
ファイルを作成します。ファイルには2行があります。各ファイルに、必要なコマンド(再度ファイル名を.に置き換えます)は上書きするのではなく、同じファイルに2行目を追加します。このスクリプトを実行した後:$filename.sh
$filename
#!/bin/bash
wget
>>
$ cat file1.sh
#!/bin/bash
wget ftp://host.com/dir1/dir2/file1/file1.sra
$ cat file2.sh
#!/bin/bash
wget ftp://host.com/dir1/dir2/file2/file2.sra
ループ本体の内側に3行目を追加できます。
chmod a+x "$filename.sh"
その後、スクリプトを実行可能にします。行のすぐ上に置きますdone
。
ファイル名にスペースやその他の特殊文字が含まれていると、さまざまなレベルで問題が発生しますが、英数字名の場合はうまく機能します。
答え2
次のコマンドを使用します。
awk -v url='ftp://host.com/dir1/dir2' '{printf "#!/bin/bash\nwget %s/%s/%s.sra\n",url,$1,$1 >$1".sh"}' filenames.txt
このコマンドを実行すると、次のように一連のファイルが現在のディレクトリに表示されます。
$ ls *.sh
file1.sh file2.sh file3.sh
各コンテンツの内容は次のようになります。
$ cat file1.sh
#!/bin/bash
wget ftp://host.com/dir1/dir2/file1/file1.sra
どのように動作しますか?
-v url='ftp://host.com/dir1/dir2'
これはaを変数
url
として定義します。awk
printf "#!/bin/bash\nwget %s/%s/%s.sra\n",url,$1,$1 >$1".sh"
これにより、必要なすべてのファイルが印刷されます。この
>$1".sh"
部分は、各シェルスクリプトがダウンロードしたファイル名にちなんでファイル名を作成し、.sh
拡張子を追加することを意味します。
答え3
for
ループprintf
とコマンド置換を使用する提案もあります$()
。
for file in $(<filenames); do
printf "%s\n%s\n" '#!/bin/bash' "wget ftp://host.com/dir1/dir2/${file}/${file}.sra" > "${file}.sh"
done
唯一重要なのは、おそらく$(<filename)
同じ$(cat filename)
ですが、もう少し高速です。