GNU “canal paralelo” não processa stdin por linhas

2

Estou super confuso sobre como usar o GNU paralelo para passar o stdin para o comando de trabalho.

Tenho o que imaginei ser um caso de uso comum realmente . Eu tenho algum processo xxd que faz algo com stdin e saídas para stdout. Eu tenho alguma maneira de gerar ou obter trabalho de outro fluxo padrão, por exemplo seq 3 , e eu posso combinar os dois e fazer uma ferramenta de poder improvisada da seguinte forma:

$ seq 3 | while read line; do echo $line | xxd; done
00000000: 310a                                     1.
00000000: 320a                                     2.
00000000: 330a                                     3.

Ótimo. Podemos ver claramente que cada invocação de xxd obtém uma linha e uma nova linha é anexada.

Isso é o que o piping para parallel faz:

$ seq 3 | parallel --pipe --recend="\n" -L 1 xxd
...

00000000: 310a 320a 330a                           1.2.3.

parallel --pipe pega todos os stdin e os envia para uma invocação de xxd , o que me confunde porque todos os parâmetros documentados e seus padrões parecem contradizer esse comportamento: --recend="\n" (o padrão) delimita trabalhos por nova linha, -L 1 (o padrão) envia no máximo uma linha para o comando.

Separadores nulos têm o mesmo problema. Eles também são passados embora textualmente:

seq 3 | tr '\n' '
$ seq 3 | while read line; do echo $line | xxd; done
00000000: 310a                                     1.
00000000: 320a                                     2.
00000000: 330a                                     3.
' | parallel --null --pipe xxd ... 00000000: 3100 3200 3300 1.2.3.

Uma explicação para esse comportamento seria apreciada, especialmente porque esses parâmetros parecem se aplicar especificamente ao modo --pipe de parallel .

    
por ThorSummoner 18.07.2018 / 00:26

2 respostas

2

Você está tão perto. -L define o registro tamanho (em linhas), mas não quantos registros devem ser enviados. Isso é controlado por -N . Por omissão, --recend é \n , pelo que não é necessário. O -L é 1, por isso não é necessário.

seq 3 | parallel --pipe -N 1 xxd
    
por 18.07.2018 / 02:18
1

Nota: esta é a minha solução original. É muito desagradável e inferior à resposta aceita . Estou deixando-o intacto por razões educacionais.

O truque é não usar o modo pipe e usar echo (ou similar) para transformar argumentos extras em stdout por trabalho:

$ seq 3 | parallel "echo {} | xxd"
00000000: 310a                                     1.
00000000: 320a                                     2.
00000000: 330a                                     3.
    
por 18.07.2018 / 00:26