Como criar uma substituição de processo dinâmica baseada na entrada (múltiplos FIFOs)?

2

Estou tentando criar várias substituições de processos com base na saída do outro comando, mas não tenho certeza de como posso conseguir isso.

Como cenário de exemplo, listei os arquivos:

touch a.txt b.txt c.txt d.doc e.doc f.pdf g.pdf h.xls i.xls

Estou fazendo a lista de extensões de arquivo disponíveis :

ls -1 *.* | awk -F. '{if (NF>1) {print $NF}}' | sort | uniq

Então, com base na minha lista dinâmica, gostaria de criar os seguintes FIFOs como:

pr -mt <(ls -1 *.doc) <(ls -1 *.pdf) <(ls -1 *.txt) <(ls -1 *.xls)

O que me permitiria imprimir cada conjunto em diferentes colunas. No entanto, a lista acima de FIFOs é codificada de modo que meu objetivo é encontrar alguma maneira em que eu possa substituir o número dinâmico de comandos (como curinga, usando eval ou xargs de alguma forma).

Outro cenário é descrito em aqui .

Não estou interessado em solução específica (solução alternativa) para o problema acima, pois esse é apenas um cenário. Estou interessado em como posso criar dinamicamente a substituição de processos no shell ou quais ferramentas adicionais posso usar para conseguir isso.

Veja também: Como criar FIFO anônimo?

    
por kenorb 27.04.2015 / 16:13

1 resposta

2

É fácil criar dinamicamente a string e avaliá-la:

eval "$(echo -n 'pr -mt '; while read ext; do echo "<(ls -1 *.$ext)"; done < list  |tr '\n' ' ' )"

onde list seria o arquivo (possivelmente um fifo) representando a lista de extensões das quais você deseja construir o comando.

<() essencialmente cria FIFOs sem nome. Uma alternativa sem evalescência pode ser usar nomes:

while read ext; do mkfifo ${ext}.pipe; ls -1 *.$ext > ${ext}.pipe & done
pr -mt *.pipe
rm *.pipe  #remove the named pipes when done

O texto acima assume que você não possui outros nomes de arquivos terminados com ".pipe" em seu diretório.

    
por 27.04.2015 / 19:24