Posso me juntar a um comando?

3

Acho join bastante útil. Permite juntar o arquivo1 ao arquivo2 nos campos-chave.

É possível fazer isso dinamicamente contra os resultados de um comando, como:

join -1 1 -2 1 file1 'curl http://example.com?code=$1&fmt=csv'

Talvez usando xargs ou pipes nomeados?

O ideal seria fazer uma "pesquisa" por registro / linha no arquivo1

    
por Neil McGuigan 26.07.2016 / 19:39

2 respostas

3

Sim, se o seu shell suportar a substituição de processos ( bash e ksh93 ), você poderá fazer assim:

$ join file1 <( yourcommand )

Isso executa o comando join com file1 e um descritor de arquivo em /dev/fd conectado à saída padrão de yourcommand (que seria seu curl thingy).

Observe que join espera que todas as entradas sejam classificadas. Requer fluxos de entrada classificados para poder analisá-los apenas uma vez. Em particular, a entrada precisa ser classificada com sort -b (ignorando espaços em branco à esquerda).

Se esse não for o caso, você pode fazer isso:

$ join <( sort -b file1 ) <( yourcommand | sort -b )
    
por 26.07.2016 / 19:45
2

Se apenas um dos arquivos de entrada precisar vir de um comando, um simples pipe será o suficiente. Use - como nome do arquivo para indicar a entrada padrão.

curl 'http://example.com?code=$1&fmt=csv' | join -1 1 -2 1 file1 -

Se ambos os arquivos precisarem vir de pipes, você precisará de algo além dos recursos básicos do shell. Ksh, bash e zsh têm substituição de processos , que permite passar a saída de um comando em qualquer lugar que um programa espera um nome de arquivo.

curl 'http://example.com?code=$1&fmt=csv' | sort |
join -1 1 -2 1 <(sort file1) -

ou equivalentemente para simetria

join -1 1 -2 1 <(<file1 | sort) \
               <(curl 'http://example.com?code=$1&fmt=csv' | sort)

O sh simples não tem substituição de processo. Uma solução portátil se você precisar de um comando para receber entrada de vários canais é usar pipes nomeados.

tmp="$(mktemp -d)"
mkfifo "$tmp/p"
sort <file1 >"$tmp/p" &
curl 'http://example.com?code=$1&fmt=csv' | sort | join -1 1 -2 1 "$tmp/p" -
rm "$tmp/p"
rmdir "$tmp"
    
por 27.07.2016 / 00:20

Tags