Um colega meu queria executar um programa FORTRAN que pegasse argumentos de arquivos e gerasse sua ordenação (melhor primeiro) de acordo com algum critério biofísico-químico obscuro. O que ele precisava eram dos 10 melhores resultados.
Embora os arquivos não sejam grandes, o problema é que ele recebeu um bash: /home/progs/bin/ardock: Argument list too long
, então criei links simbólicos de 6 dígitos para os arquivos e os dei como argumento, o que funcionou ;-)
Agora, se o número de arquivos for realmente muito grande para que o truque acima funcione, o que você pode fazer para obter o melhor de todos eles? Você precisa classificar os arquivos por partes e comparar os melhores com os melhores com algo assim?
#!/bin/bash
best10() { ardock "$@" | head -n 10; }
export -f best10
find . -name '*.dat' -exec bash -c 'best10 "$@"' _ {} + |
xargs bash -c 'best10 "$@"' _ |
xargs bash -c 'best10 "$@"' _ |
xargs bash -c ... | ... | ...
O problema aqui é que o número necessário xargs
não é conhecido antecipadamente, então como você pode fazer um loop?
Eu sugeriria resolver esse problema por meio de um torneio iterativo.
A ideia é que na primeira rodada você divida arbitrariamente toda a sua produção em grupos de N. Os 10 primeiros colocados de cada grupo avançam para a próxima rodada, onde você os divide novamente em grupos de N.
Isso garante que você esteja entre os 10 primeiros, assumindo que Ardock seja determinístico e forneça um pedido total.
Aqui está o código. Comecei criando uma versão de teste do seu programa Ardock. Ele classifica os argumentos dados pelo hash e os imprime. Isso é só para que eu tenha algo para testar.
A seguir, aqui está o script Bash que administra o torneio.
Explicação:
0.candidates
é criado. Contém os nomes de todos os arquivos possíveis que você deseja testar, separados por novas linhas. No meu caso, são apenas os primeiros 1.000 números inteiros. Como se trata de um arquivo, ele pode ser do tamanho que você desejar.$MAX_ARGS
cada invocação do ardock.$MAX_ARGS
: Isso deve ser maior$KEEP
para progredir, mas não precisa ser muito maior. Por exemplo, se forem 20 e 10, a cada rodada do torneio, o número de candidatos diminui por um fator de 2. Aumentar$MAX_ARGS
torna o algoritmo mais rápido.)ardock_wrapper
é responsável por obter as$KEEP
linhas superiores de cada saída do ardock.1.candidates
.Este código foi testado em Linux usando Bash 5.0.17.
Talvez algo assim (não testado):
Isso pressupõe que seus nomes de arquivos não contenham novas linhas, pois suas chamadas existentes
head
exargs
falhariam se o fizessem. Ele também pressupõe que você esteja usando o shell builtinprintf
, em vez de uma versão externa dele, portanto não haverá um problema de ARG_MAX.