Eu tenho um script s1
que gera uma lista de números separados por ',' por exemplo 1,2,3,4
. Agora, quero atribuir esses números ao script s2
como argumentos, para que o s2 seja executado em cada um deles e produza o resultado em uma linha separada. Por exemplo, se s2 multiplica números por dois, este seria o resultado que estou procurando:
2
4
6
8
O que estou fazendo agora é:
s1 | xargs -d "," | xargs -n1 s2
Mas sinto que estou fazendo isso de uma maneira tão tola! Então, minha pergunta é:
Qual é a maneira correta de fazer isso?
Meu problema com a minha solução é que ele está chamando xargs duas vezes e iterando sobre a entrada duas vezes, o que não é razoável para meus olhos, é claro, por meio do desempenho! A resposta xargs -d "," -n1
parece boa, mas não tenho certeza se está apenas repetindo uma vez. Caso isso aconteça, verifique isso em sua resposta e eu aceito. A propósito, prefiro não usar o Perl, pois ele ainda está iterando duas vezes e também o Perl pode não existir em muitos sistemas.
s1 | xargs -d "," -n1 s2
Respostas:
Isso deve funcionar igualmente:
Caso de teste:
Resultado:
Se
s1
gerar essa lista seguida por um caractere de nova linha, você deverá removê-la, caso contrário a última chamada estaria com em4\n
vez de4
:fonte
Se
s2
puder aceitar vários argumentos, você poderá:que substitui temporariamente o IFS por vírgula, tudo em um subshell, para que
s2
a saída sejas1
dividida por vírgulas. O subshell é uma maneira abreviada de alterar o IFS sem salvar o valor anterior ou redefini-lo.Uma versão anterior desta resposta estava incorreta, provavelmente devido a uma configuração restante do IFS, corrompendo os resultados. Obrigado a ilkkachu por apontar meu erro .
Para fazer um loop manual sobre as saídas e fornecê-las individualmente
s2
, demonstrando aqui a economia e a redefinição do IFS:ou execute os bits IFS em um subshell como antes:
fonte
bash -c 'IFS=, printf "%s\n" $(echo 1,2,3)'
imprime1,2,3
no meu sistema, ou seja, não há divisão./usr/bin/printf
e/bin/echo
(IFS=,; printf "%s\n" $(echo 1,2,3))
, por outro lado, deve funcionar.Tente o seguinte:
fonte
tr ',' '\n'
? Não há necessidade de chamar algo tão (relativamente) pesado como Perl e expressões regulares.