Buen camino
Normalmente no puede hacer esto con grep pero puede usar otras herramientas. AWK ya se mencionó, pero también puede usarlo sedasí:
sed -e '1p' -e '/youpattern/!d'
Cómo funciona:
La utilidad Sed funciona en cada línea individualmente, ejecutando comandos específicos en cada una de ellas. Puede tener múltiples comandos, especificando varias -eopciones. Podemos anteponer cada comando con un parámetro de rango que especifica si este comando debe aplicarse a una línea específica o no.
"1p" es un primer comando. Utiliza un pcomando que normalmente imprime todas las líneas. Pero lo anteponemos con un valor numérico que especifica el rango al que debe aplicarse. Aquí, usamos lo 1que significa primera línea. Si desea imprimir más líneas, puede usar x,ypdónde xestá la primera línea para imprimir, yes la última línea para imprimir. Por ejemplo, para imprimir las primeras 3 líneas, usaría1,3p
El siguiente comando es el dque normalmente elimina todas las líneas del búfer. Antes de este comando ponemos yourpatternentre dos /caracteres. Esta es la otra forma (primero fue especificar en qué líneas como hicimos con el pcomando) de direccionar las líneas en las que el comando debería estar ejecutándose. Esto significa que el comando solo funcionará para las líneas que coinciden yourpattern. Excepto, usamos el !carácter antes del dcomando que invierte su lógica. Entonces ahora eliminará todas las líneas que no coinciden con el patrón especificado.
Al final, sed imprimirá todas las líneas que quedan en el búfer. Pero eliminamos las líneas que no coinciden del búfer, por lo que solo se imprimirán las líneas coincidentes.
Para resumir: imprimimos la primera línea, luego eliminamos todas las líneas que no coinciden con nuestro patrón de la entrada. Resto de las líneas se imprimen (tan sólo las líneas que hacen coincidir con el patrón).
Problema de primera línea
Como se mencionó en los comentarios, hay un problema con este enfoque. Si el patrón especificado coincide también con la primera línea, se imprimirá dos veces (una por pcomando y otra por una coincidencia). Podemos evitar esto de dos maneras:
Agregar 1dcomando después 1p. Como ya mencioné, el dcomando elimina líneas del búfer y especificamos su rango con el número 1, lo que significa que solo eliminará la primera línea. Entonces el comando seríased -e '1p' -e '1d' -e '/youpattern/!d'
Usando el 1bcomando, en lugar de 1p. Es un truco. bEl comando nos permite saltar a otro comando especificado por una etiqueta (de esta manera se pueden omitir algunos comandos). Pero si esta etiqueta no se especifica (como en nuestro ejemplo) simplemente salta al final de los comandos, ignorando el resto de los comandos para nuestra línea. Entonces, en nuestro caso, el último dcomando no eliminará esta línea del búfer.
Ejemplo completo:
ps aux | sed -e '1b' -e '/syslog/!d'
Usando punto y coma
Algunas sedimplementaciones pueden ahorrarle algo de tipeo usando punto y coma para separar comandos en lugar de usar múltiples -eopciones. Entonces, si no te importa ser portátil, el comando sería ps aux | sed '1b;/syslog/!d'. Funciona al menos en GNU sede busyboximplementaciones.
Manera loca
Aquí hay, sin embargo, una forma bastante loca de hacer esto con grep. Definitivamente no es óptimo, estoy publicando esto solo con fines de aprendizaje, pero puede usarlo, por ejemplo, si no tiene ninguna otra herramienta en su sistema:
ps aux | grep -n '.*' | grep -e '\(^1:\)\|syslog'
Cómo funciona
Primero, usamos la -nopción para agregar números de línea antes de cada línea. Queremos numerar todas las líneas que estamos haciendo coincidir .*, cualquier cosa, incluso una línea vacía. Como se sugiere en los comentarios, también podemos hacer coincidir '^', el resultado es el mismo.
Luego estamos usando expresiones regulares extendidas para que podamos usar \|caracteres especiales que funcionen como OR. Entonces, hacemos coincidir si la línea comienza con 1:(primera línea) o contiene nuestro patrón (en este caso, su syslog).
Problema de números de línea
Ahora el problema es que estamos obteniendo estos números de línea feos en nuestra salida. Si esto es un problema, podemos eliminarlos de cutesta manera:
ps aux | grep -n '.*' | grep -e '\(^1:\)\|syslog' | cut -d ':' -f2-
-dLa opción especifica delimitador, -fespecifica los campos (o columnas) que queremos imprimir. Por lo tanto, queremos cortar cada línea en cada :carácter e imprimir solo la segunda y todas las columnas posteriores. Esto elimina efectivamente la primera columna con su delimitador y esto es exactamente lo que necesitamos.
ackson tan útiles, y porperlúltimo se dispararonsed,awk, etc en popularidad: es importante que las partes en suma en un todo coherente.