gnu paralelo remove escape antes dos caracteres de espaço no comando

gnu paralelo remove escape antes dos caracteres de espaço no comando

Atualmente estou testando o gnu paralelo para distribuir um comando de comparação em vários servidores usando o bash. Em sua função mais básica, este comando de comparação usa duas entradas para comparar (acessos ao banco de dados Oracle) e requer um nome de arquivo de saída via -o. Pelo menos uma ação carregar, salvar ou fazer upload direto é exigida pelo programa.

compare -o cmp.input1.input2.dat Input1 Input2

Eu tenho alguns milhares desses pares de entrada e crio um arquivo com todas as combinações para que cada linha contenha o nome do arquivo de saída e os identificadores do banco de dados exigidos pelo programa

#test_parallel
-o cmp.input1.input2.dat Input1 Input2
-o cmp.input1.input3.dat Input1 Input3
-o cmp.input2.input3.dat Input2 Input3
[...]

e execute o comando usando paralelo, porém o comando compare falha

parallel -a test_parallel "compare {}"
ERROR: No action specified for results (load, save or direct upload)
usage: compare [-u][-o <file>] query target

usando --dryruno modo, é isso que o paralelo executa:

compare -o\ cmp.input1.input2.dat\ Input1\ Input2

Por alguma razão que não entendo, o espaço em branco escapado não é tratado corretamente pelo programa de comparação. A execução deste comando no bash resulta exatamente na mesma mensagem de erro. Remover o escape após o sinalizador -o (eu poderia mover o -o para o comando paralelo) resulta em um erro de "muitos argumentos". A remoção de todos os escapes executa o comando conforme o esperado.

É possível dizer paralelo para não imprimir o escape na chamada de comando? Parece que não encontrei nada na documentação, exceto que este é o comportamento padrão esperado, conforme indicado porparallel --shellquote

Responder1

GNU Parallel trata a entrada como um único argumento e cita-a para que você possa usar nomes de arquivos com segurança como:

My brother's 12" records costs 30$ each.txt

No seu caso, você deseja que o argumento seja analisado pelo shell, para que os espaços não fiquem entre aspas:

parallel -a test_parallel eval compare {}

Ou você pode dividir no espaço:

parallel --colsep ' ' -a test_parallel compare {1} {2} {3} {4}

Mas como você deseja comparar tudo contra tudo, você pode fazer isso com muito mais elegância:

parallel cmp -o ../out/cmp.{1}.{2} {1} {2} ::: Input* ::: Input*

Isso comparará todas as entradas* com todas as entradas*. Com --resultsvocê pode obter as saídas bem estruturadas em um diretório:

parallel --results out/ cmp {1} {2} ::: Input* ::: Input*

Mas se quiser pular a corrida cmp InputY InputXdepois de já ter corrido cmd InputX InputY, você pode fazer o seguinte:

parallel --results out/ cmp {=1' $arg[1] ge $arg[2] and $job->skip();' =} {2} ::: Input* ::: Input*

Editar:

A versão 20190722 introduz a função uq.

parallel -a test_parallel compare {=uq=}

uqé uma função Perl. Quando chamado, o GNU Parallel evitará citar essa string de substituição. Assim, você pode misturar strings de substituição entre aspas e sem aspas:

parallel echo {} = {=uq=} ::: \$PWD
# You can change $_ if you want: uq() is a normal perl function
parallel echo {}ME = '{=uq(); $_.="ME"=}' ::: \$HO \$LOGNA

informação relacionada