Combine vários comandos unix em uma saída

9

Eu preciso procurar em nossos registros de e-mail por um endereço de e-mail específico. Nós mantemos um arquivo atual chamado maillog , bem como uma semana de arquivos .bz2 na mesma pasta. Atualmente, estou executando os seguintes comandos para pesquisar o arquivo:

grep [email protected] maillog
bzgrep [email protected] *.bz2

Existe uma maneira de combinar os comandos grep e bzgrep em uma única saída? Dessa forma, eu poderia canalizar os resultados combinados para um único e-mail ou um único arquivo.

    
por Ben McCormack 08.03.2011 / 23:03

5 respostas

24

Outra maneira é

{ grep ...; bzgrep ...;} >file

&& tem a dificuldade de o bzgrep não ser executado se o grep falhar.

Observe o espaço obrigatório após a chave de abertura e o ponto-e-vírgula após o último comando. Como alternativa, você pode usar a sintaxe de subshell (parênteses em vez de chaves), que não é tão exigente:

(grep ...; bzgrep ...) >file
    
por 08.03.2011 / 23:25
11

O bzgrep automaticamente padroniza o grep normal se um arquivo não for comprimido em bzip. Assim, o seguinte deve ser suficiente:

bzgrep [email protected] maillog *bz2 | mail -s "logs yay" someuser@blah

oh, claro, aqui está minha solução obrigatória GNU Parallel também:

parallel -m bzgrep [email protected] ::: maillog* *bz2 | mail -s "logs yay" someuser@blah

que pode ser muito mais rápido se você estiver verificando muitos arquivos.

    
por 09.03.2011 / 00:01
2

Aqui está outra maneira de fazer isso (assumindo que você esteja executando o bash, o que provavelmente você é):

cat <(bzgrep ...) <(grep ...)

Aqui o bash está alimentando de forma transparente a saída dos comandos bzgrep e grep no cat como se fossem arquivos (e eles estão sob o capô, detalhes no url na parte inferior).

No seu caso particular, eu recomendaria a solução de Phil, mas o acima é um bom truque para guardar na sua bolsa.

Se estiver interessado, pode ler mais aqui: link

    
por 09.03.2011 / 02:11
1

No momento da minha escrita, a sintaxe da resposta aceita estava errada para a maioria, se não todas, shells derivadas de Bourne, incluindo bash . Eu sugeri uma edição para o topo e aceitei uma resposta para corrigir isso, mas também estava inclinado a adicionar todas essas outras informações, e isso seria mais uma reescrita do que uma edição.

Você pode usar comandos compostos:

{ grep ...; bzgrep ...; } >file

.. ou subshells (observe os parênteses em vez de chaves):

(grep ...; bzgrep ...) >file

.. para agrupar os comandos. O modo subshell tem uma sintaxe mais agradável (perdoa mais a falta de espaço em branco e permite omitir o último ponto e vírgula), mas ele bifurca um novo processo ou "finge" fazer com que os comandos sejam executados em um ambiente limpo. Ambos têm vantagens dependendo do que você quer fazer, o que não importa aqui, mas vale a pena procurar se você quer mais proficiência com o shell.

Observação: você também pode usar o pipelining com esses truques para fazer algo assim:

{ grep ...; bzgrep ...; } | less

P.S. Se você não se importar com a ordenação das correspondências em sua saída combinada, você poderia usar um único & entre os dois comandos, assim: { grep ... & bzgrep ...; } . Então os dois comandos são executados simultaneamente: o grep é iniciado eo shell o coloca em segundo plano, então o shell executará o bzgrep . (Mas há uma pequena ressalva com isso, com a explicação envolvendo o redirecionamento de arquivos e buffer de fluxo de arquivos potencialmente fazendo com que uma porção muito pequena das linhas no arquivo de saída seja dividida / desconfigurada: se você veria isso dependeria de como sua grep , bzgrep e libc stdio.h funções são implementadas.Na maioria das implementações, acredito que canalizar o comando antes de redirecionar para um arquivo evitará o problema, portanto, você pode fazer { foo & bar; } | cat - >file como uma solução alternativa. / p>     

por 14.03.2016 / 06:39
0

Você pode vincular os comandos com & & que permitirá que você execute cada comando.

você também pode adicionar > > textfile.txt ao final de cada comando e faça com que a saída atinja um arquivo e envie esse arquivo para fora.

    
por 08.03.2011 / 23:08