Bom caminho
Normalmente você não pode fazer isso com o grep, mas pode usar outras ferramentas. O AWK já foi mencionado, mas você também pode usar o sedseguinte:
sed -e '1p' -e '/youpattern/!d'
Como funciona:
O utilitário Sed trabalha em cada linha individualmente, executando comandos especificados em cada uma delas. Você pode ter vários comandos, especificando várias -eopções. Podemos acrescentar cada comando com um parâmetro range que especifica se esse comando deve ser aplicado a uma linha específica ou não.
"1p" é o primeiro comando. Ele usa o pcomando que normalmente imprime todas as linhas. Mas o anexamos com um valor numérico que especifica o intervalo ao qual ele deve ser aplicado. Aqui, usamos o 1que significa primeira linha. Se você quiser imprimir mais linhas, poderá usar x,yponde xestá a primeira linha a ser impressa, a yúltima linha a ser impressa. Por exemplo, para imprimir as 3 primeiras linhas, você usaria1,3p
O próximo comando é o dque normalmente exclui todas as linhas do buffer. Antes deste comando, colocamos yourpatternentre dois /caracteres. Essa é a outra maneira (primeiro foi especificar em quais linhas, como fizemos com o pcomando), de endereçar as linhas nas quais o comando deve estar em execução. Isso significa que o comando funcionará apenas para as linhas correspondentes yourpattern. Exceto, usamos !caractere antes do dcomando que inverte sua lógica. Portanto, agora ele removerá todas as linhas que não correspondem ao padrão especificado.
No final, o sed imprimirá todas as linhas restantes no buffer. Mas removemos as linhas que não correspondem ao buffer, para que apenas as linhas correspondentes sejam impressas.
Resumindo: imprimimos a primeira linha e excluímos todas as linhas que não correspondem ao nosso padrão da entrada. Resto das linhas são impressos (para que apenas as linhas que fazem corresponder ao padrão).
Problema de primeira linha
Como mencionado nos comentários, há um problema com essa abordagem. Se o padrão especificado corresponder também à primeira linha, ele será impresso duas vezes (uma vez por pcomando e uma vez por causa de uma correspondência). Podemos evitar isso de duas maneiras:
Adicionando 1dcomando depois 1p. Como já mencionei, o dcomando exclui as linhas do buffer e especificamos seu intervalo pelo número 1, o que significa que ele excluirá apenas a primeira linha. Então o comando seriased -e '1p' -e '1d' -e '/youpattern/!d'
Usando o 1bcomando, em vez de 1p. É um truque. bO comando nos permite pular para outro comando especificado por um rótulo (dessa maneira, alguns comandos podem ser omitidos). Mas se esse rótulo não for especificado (como no nosso exemplo), ele simplesmente pula para o final dos comandos, ignorando o restante dos comandos da nossa linha. Portanto, no nosso caso, o último dcomando não removerá essa linha do buffer.
Exemplo completo:
ps aux | sed -e '1b' -e '/syslog/!d'
Usando ponto e vírgula
Algumas sedimplementações podem economizar digitação usando ponto-e-vírgula para separar comandos, em vez de usar várias -eopções. Portanto, se você não se importa em ser portátil, o comando seria ps aux | sed '1b;/syslog/!d'. Funciona pelo menos em GNU sede busyboximplementações.
Maneira louca
Aqui está, no entanto, uma maneira bastante louca de fazer isso com o grep. Definitivamente não é o ideal, estou publicando isso apenas para fins de aprendizado, mas você pode usá-lo, por exemplo, se não tiver nenhuma outra ferramenta no seu sistema:
ps aux | grep -n '.*' | grep -e '\(^1:\)\|syslog'
Como funciona
Primeiro, usamos a -nopção para adicionar números de linha antes de cada linha. Queremos numerar todas as linhas com as quais estamos combinando .*- qualquer coisa, até a linha vazia. Como sugerido nos comentários, também podemos combinar '^', o resultado é o mesmo.
Então, estamos usando expressões regulares estendidas para que possamos usar \|caracteres especiais que funcionam como OR. Então, combinamos se a linha começa com 1:(primeira linha) ou contém nosso padrão (nesse caso, é syslog).
Problema de números de linha
Agora, o problema é que estamos obtendo esses números de linha feios em nossa saída. Se este for um problema, podemos removê-los com cut, desta forma:
ps aux | grep -n '.*' | grep -e '\(^1:\)\|syslog' | cut -d ':' -f2-
-dopção especifica delimitador, -fespecifica campos (ou colunas) que queremos imprimir. Portanto, queremos cortar cada linha de cada :caractere e imprimir apenas a segunda e todas as colunas subseqüentes. Isso efetivamente remove a primeira coluna com seu delimitador e é exatamente isso que precisamos.
acksão tão úteis, e por queperlpassado disparoused,awketc. em popularidade: é importante para as partes para resumir em um todo coerente.