Anexar e gravar o arquivo de nome variável da lista de variáveis

3

Eu gostaria de criar vários shell scripts 'wget' para baixar um lote de arquivos consideravelmente grandes (~ 3GB) usando nosso cluster HPC. Os nomes dos arquivos são armazenados em filenames.txt, assim:

$cat filenames.txt
file1
file2
file3
...

e os URLs que eu gostaria de usar são estruturados da seguinte forma:

ftp://host.com/dir1/dir2/file1/file1.sra
ftp://host.com/dir1/dir2/file2/file2.sra
ftp://host.com/dir1/dir2/file3/file3.sra

Eu gostaria de criar um script de shell para cada wget e escrevê-lo em um arquivo chamado de variável. Por exemplo, arquivo1.sh deve conter:

#!/bin/bash
wget ftp://host.com/dir1/dir2/file1/file1.sra

e o arquivo2.sh deve conter:

#!/bin/bash
wget ftp://host.com/dir1/dir2/file2/file2.sra

Como você pode ver, o padrão a ser correspondido é 1) O URL e 2) o nome do arquivo a ser escrito. Como eu 'anexaria' a URL ao nome do arquivo e, em seguida, gravaria em um arquivo .sh com o mesmo nome?

    
por aish1249 01.02.2015 / 02:44

3 respostas

0

Você pode fazer um loop de shell muito simples para fazer isso:

while read filename
do
    echo '#!/bin/bash' > $filename.sh
    echo "wget ftp://host.com/dir1/dir2/$filename/$filename.sra" >> $filename.sh
done < filenames.txt

Isso lê cada linha de filenames.txt e chama filename e, em seguida, cada uma grava um arquivo chamado $filename.sh , em que $filename é substituído pela linha do arquivo. Esse arquivo tem duas linhas: #!/bin/bash , em cada arquivo e, em seguida, o comando wget desejado, novamente com o nome do arquivo substituído em >> , está anexando a segunda linha ao mesmo arquivo, em vez de sobrescrevê-lo. Depois de executar este script:

$ 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

Você pode querer adicionar uma terceira linha dentro do corpo do loop:

chmod a+x "$filename.sh"

para tornar os scripts executáveis posteriormente. Coloque isso imediatamente acima da linha done .

Se qualquer um dos seus nomes de arquivo tiver espaços ou outros caracteres especiais, isso irá desmoronar (em vários níveis), mas, para nomes alfanuméricos, tudo ficará bem.

    
por 01.02.2015 / 03:00
0

Use este comando:

awk -v url='ftp://host.com/dir1/dir2' '{printf "#!/bin/bash\nwget %s/%s/%s.sra\n",url,$1,$1 >$1".sh"}' filenames.txt

Após este comando ser executado, haverá uma série de arquivos no diretório atual, como:

$ ls *.sh
file1.sh  file2.sh  file3.sh

O conteúdo de cada um é parecido com:

$ cat file1.sh
#!/bin/bash
wget ftp://host.com/dir1/dir2/file1/file1.sra

Como funciona

  • -v url='ftp://host.com/dir1/dir2'

    Isso define uma variável url como awk .

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

    Isto imprime cada arquivo que você precisa. A parte >$1".sh" significa que cada script de shell é gravado em um arquivo com o nome do arquivo que ele baixa com uma extensão .sh adicionada.

por 01.02.2015 / 03:02
0

Ainda outra proposta, usando for loop, printf e substituição de comando $() :

for file in $(<filenames); do
    printf "%s\n%s\n" '#!/bin/bash' "wget ftp://host.com/dir1/dir2/${file}/${file}.sra" > "${file}.sh"
done

A única parte não-trival é provavelmente $(<filename) , o que equivale a $(cat filename) , mas um pouco mais rápido.

    
por 01.02.2015 / 03:05

Tags