Usando xargs com entrada de um arquivo

36

Digamos que eu tenha um arquivo com o seguinte

bob
john
sue

Agora, esses padrões de URL diretamente corrospond para (neste caso), como http://example.com/persons/bob.tar , john.tar , sue.tar .

Eu gostaria de pegar essas linhas e executá-las em xargs . Eu não sei o que é passado para o comando que está sendo executado embora. Como eu acesso o parâmetro a partir do prompt (digamos que quero simplesmente ecoar cada linha como cat file | xargs echo $PARAM ) ou de um script bash.

    
por Josh K 29.10.2010 / 03:54

7 respostas

59

answer de Michael está certo, e deve resolver o seu problema. Correndo

cat file | xargs -I % curl http://example.com/persons/%.tar

fará download dos arquivos bob.tar john.tar. sue.tar conforme o esperado.

MAS : o gato aqui é inútil

prefere usar:

<file xargs -I % curl http://example.com/persons/%.tar
    
por 29.10.2010 / 09:36
15

Acho que você está perguntando como inserir as linhas individuais obtidas de xargs 'stdin no meio de um comando, em vez de apenas colá-las no final sempre. Em caso afirmativo, o sinalizador -I aceita um argumento replacement-string ; xargs substituirá replacement-string no comando pela linha lida de stdin:

$ cat file | xargs -I foobar curl http://example.com/foobar.tar
    
por 29.10.2010 / 04:46
9
$ man xargs
...
       --arg-file=file
       -a file
              Read items from file instead of standard input.  If you use this
              option,  stdin  remains unchanged when commands are run.  Other-
              wise, stdin is redirected from /dev/null.
...

Você também pode definir --delimiter= / -d para '\n' .

Por outro lado, se você está apenas tentando transformar cada linha do arquivo em um URL,

$ sed -e 's#.*#http://example.com/persons/&.tar#' file

irá fazer, e se você quiser buscar todos eles, apenas coloque isso em | wget -i .

    
por 30.10.2010 / 07:07
8

outra maneira com looping de shell:

for i in 'cat file'; do curl -I http://foo.com/$i; done

você também pode executar cada iteração em segundo plano adicionando & antes do último ponto e vírgula - para downloads muito grandes isso pode ser útil

    
por 30.10.2010 / 09:08
2

Com o GNU Parallel você pode fazer:

cat urls | parallel curl {} ">" {/}

Ou:

cat persons | parallel curl http://example.com/persons/{}.tar ">" {}.tar

Assista ao vídeo de introdução do GNU Parallel para saber mais: link

    
por 05.12.2010 / 13:00
0

Esta é uma versão mais geral da resposta de Stefan: mas estou usando o awk no meio para preparar a "string" exata que gostaria que os xargs executassem. E então o xargs está usando o bash para fazer o "trabalho" real.

É um pouco exagerado para este exemplo, mas é uma solução geral que com algumas modificações pode resolver muitos problemas ...

cat file | awk '{print "curl http://example.com/persons/"$1".tar"}' | xargs -0 bash -c
    
por 06.12.2010 / 17:57
0

while read VAR; do ... done loop é simples, mas muito versátil:

while read word; do wget http://example.com/persons/$word; done < file
    
por 20.05.2012 / 00:31