从变量列表中追加并写出变量命名的文件

从变量列表中追加并写出变量命名的文件

我想创建多个“wget”shell 脚本来使用我们的 HPC 集群下载一批相当大(~3GB)的文件。文件的名称存储在 filenames.txt 中,如下所示:

$cat filenames.txt
file1
file2
file3
...

我想从中获取的网址的结构如下:

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 创建一个 shell 脚本,并将其写入一个名为变量本身的文件中。例如,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

您可以创建一个非常简单的 shell 循环来执行此操作:

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,然后为每一行写出一个名为 的文件$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

您可能想在循环体内添加第三行:

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 定义urlawk变量。

  • printf "#!/bin/bash\nwget %s/%s/%s.sra\n",url,$1,$1 >$1".sh"

    这会打印出您需要的每个文件。该>$1".sh"部分意味着每个 shell 脚本都会写入一个以它下载的文件命名并.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),但速度更快一点。

相关内容