Une dois arquivos não classificados com POSIX? [duplicado]

3

Como a entrada para join deve ser classificada, geralmente o comando é chamado de modo semelhante para:

join <(sort file1) <(sort file2)

Isto não é portátil, pois utiliza a substituição de processos, que não é especificada pelo POSIX.

join também pode usar a entrada padrão, especificando - como um dos argumentos do arquivo. No entanto, isso só permite classificar um dos arquivos por meio de um pipeline:

sort file1 | join - <(sort file2)

Parece que deve haver uma maneira simples de realizar a classificação de ambos os arquivos e, em seguida, unir os resultados usando apenas recursos especificados pelo POSIX. Talvez algo usando o redirecionamento para um terceiro descritor de arquivo, ou talvez seja necessário criar um FIFO. No entanto, estou com dificuldades para visualizá-lo.

Como join pode ser usado POSIXly em arquivos não classificados?

    
por Wildcard 26.01.2017 / 21:34

1 resposta

4

Você pode fazer isso com dois pipes nomeados (ou, claro, você pode usar um pipe nomeado e stdin):

mkfifo a b
sort file1 > a &
sort file2 > b &
join a b

A substituição de processos funciona essencialmente configurando esses fifos (usando /dev/fd/ em vez de pipes nomeados quando disponíveis). Por exemplo, no bash:

$ echo join <(sort file1) <(sort file2)
join /dev/fd/63 /dev/fd/62

Observe como o bash substituiu o processo por um nome de arquivo, em /dev/fd . (Por exemplo, /dev/fd/ , novas versões suficientes de zsh, bash e ksh93 usarão pipes nomeados.) Isso fica aberto quando invocar join , então quando join abrir esses, ele lerá os dois sort s. Você pode vê-los com algum truque:

$ sh -c 'lsof -a -d 0-999 -p $$; exit' <(sort file1) <(sort file2)
COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
sh      1894 anthony    0u   CHR  136,5      0t0      8 /dev/pts/5
sh      1894 anthony    1u   CHR  136,5      0t0      8 /dev/pts/5
sh      1894 anthony    2u   CHR  136,5      0t0      8 /dev/pts/5
sh      1894 anthony   62r  FIFO   0,10      0t0 237085 pipe
sh      1894 anthony   63r  FIFO   0,10      0t0 237083 pipe

(O exit é para evitar uma otimização comum em que o shell não é bifurcado quando há apenas um comando para executar).

    
por 26.01.2017 / 21:54