¿Cómo puedo "fusionar" patrones en una sola línea?


10

Estoy haciendo grep and sed y obtengo 2 líneas de un archivo que me interesa. ¿Cómo puedo obtener estas líneas en una sola línea que termine con el nuevo carácter de línea?
Ahora estoy obteniendo:

pattern1  
pattern2  

Me gustaría conseguir pattern1 pattern2 \n


1
¿Puedes compartir más datos de muestra?
slm

Uso printf %s\\n pattern1 pattern2 | sed '$!N;s/\n/ /'
Valentin Bajrami

Pegar es la herramienta para el trabajo, si tiene la intención de combinar varias líneas de salida en una sola.
slm

alguna herramienta específica? ¿Cómo planeas hacer esto?
Braiam

Respuestas:


7

paste:

{...pipeline...} | paste -d " " - -

Eso dice: "lea una línea de stdin (la primera -), lea otra línea de stdin (la segunda -), luego únalas con un espacio"


una técnica específica de bash:

$ x=$(grep -o pattern. test.txt)
$ echo "$x"
pattern1
pattern2
$ mapfile -t <<< "$x"
$ echo "${MAPFILE[*]}"
pattern1 pattern2

ref: http://www.gnu.org/software/bash/manual/bashref.html#index-mapfile


¿Qué es - -? ¿Es el comando así?
Jim

@ Jim: sí, eso es correcto. Esos le dicen pastecómo quiere que procese la entrada. 2 a la vez. Agregue más para hacer 3 a la vez. seq 10 | paste -d " " - - .
slm

6

Pondré tres versiones diferentes métodos en una fila

AWK

printf %s\\n pattern1 pattern2 | awk -vRS="\n" -vORS=" " '1; END {print RS}'

SED

printf %s\\n pattern1 pattern2 | sed '$!N;s/\n/ /'

TR

printf %s\\n pattern1 pattern2 | tr '\n' ' '; echo

Y hay muchos más.


La trsolución se tragará la nueva línea final, por lo que es posible que desee agregar ; echoa esa
glenn jackman

@glennjackman, ¡ah! Gracias por la pista. Sin embargo, eres libre de modificar la respuesta. Me perdí ese bit!
Valentin Bajrami

2

puede hacerlo usando el script de shell o en la línea de comandos, simplemente coloque la salida del comando en una variable y luego echo:

# x=$(grep -e "pattern1\|pattern2" test)
# printf '%s\n' "$x"
pattern1 pattern2

sin comillas, la variable también está sujeta a la expansión del nombre de archivo, por lo que si tiene caracteres globales (como *o ?) en el resultado, los valores pueden cambiar.
Glenn Jackman

@glennjackman, gracias por mencionar esto, ¿cómo podemos solucionar esto?
Nidal

@Networker al no usar backticks, sino a $()través de printfprintf '%s\n' "$x"
Valentin Bajrami

Esperaría que printf '%s\n' "$x"eso NO elimine la nueva línea "interna".
Glenn Jackman

2

Con sed, puedes hacer esto:

<your previous commands> | sed '{N; s/\n/ /}'
  • N;le dice sedque agregue la siguiente línea en el espacio del patrón, por lo que ahora sedestá trabajando con ambas líneas.
  • s/\n/ / reemplaza el carácter de nueva línea con un espacio, "fusionando" las dos líneas juntas.

2

Una manera simple, salida de tubería a xargs:

$ echo -e 'a\nb' | xargs
a b

Esto solo funciona con una salida pequeña, porque está limitado por el máximo de caracteres por línea de comando. El valor más grande depende del sistema, puede obtener este valor utilizando getconf ARG_MAX.


1
( set -f; IFS='
'; printf '%s %s\n' $(grepcmd <input)
) >output

IFS estará encantado de comerlo si lo desea.


-1

envuelva su sed / grep en backticks

cuando tu comando original era:

grep -i 'foo' mylog.log | sed 's/bar/baz/gi'

su nuevo comando sería:

`grep -i 'foo' mylog.log | sed 's/bar/baz/gi'`

No obtiene los espacios entre líneas, pero siempre puede agregar otro tubo de sed:

 | sed 's/$/ /'

1
UH no. Eso ejecutará la salida del comando sed.
Glenn Jackman
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.