¿Cómo concatenar múltiples líneas de salida en una línea?

158

Si ejecuto el comando cat file | grep pattern, obtengo muchas líneas de salida. ¿Cómo se concatenan todas las líneas en una línea, reemplazando efectivamente cada una "\n"con "\" "(termina con "seguido de espacio)?

cat file | grep pattern | xargs sed s/\n/ /g no funciona para mi

T. Webster
fuente
Por cierto: (1) necesita poner su sedscript entre comillas simples para que Bash no se meta con él (ya que sed s/\n/ /gllama sedcon dos argumentos, a saber, s/n/y /g); (2) ya que desea que la salida de cat file | grep patternser la entrada a sed, no los argumentos a sed, es necesario eliminar xargs; y (3) no es necesario cataquí, ya que greppuede tomar un nombre de archivo como segundo argumento. Entonces, deberías haberlo intentado grep pattern file | sed 's/\n/ /g'. (En este caso no habría funcionado, por las razones dadas en el enlace de arriba, pero ahora ya sabes para el futuro.)
ruakh
similar a " stackoverflow.com/questions/2764051/… "
Shervin Emami
¿Pregunta con 68 votos (140k vistas) duplicada con una publicación que solo tiene 1 voto (12k vistas)? Esto no esta bien.
kenorb

Respuestas:

231

Use tr '\n' ' 'para traducir todos los caracteres de nueva línea a espacios:

$ grep pattern file | tr '\n' ' '

Nota: greplee archivos, catconcatena archivos. No hacerlo cat file | grep!

Editar:

trsolo puede manejar traducciones de un solo carácter. Puede usar awkpara cambiar el separador de registro de salida como:

$ grep pattern file | awk '{print}' ORS='" '

Esto transformaría:

one
two 
three

a:

one" two" three" 
Chris Seymour
fuente
3
Usted termina con un espacio no deseado al final con este enfoque.
sorin
1
Debe agregar echo ""al final para agregar una nueva línea antes del texto de solicitud.
nexayq
1
Esto funciona bien, sin embargo, no quiero que el separador aparezca en la última entrada. Ejemplo, según tu ", aparece como one" two" three", sin embargo, me gustaría que aparezca como one" two" three. Tenga en cuenta que los últimos tres no tienen paréntesis. ¿Algunas ideas?
oink
2
@oink podría canalizar los resultados sed '$s/..$//'para eliminar los últimos 2 caracteres en la última línea.
Chris Seymour
3
Si desea reemplazar las nuevas líneas con nada, debe usar la --deleteopción ya que el valor predeterminado espera dos argumentos. por ej tr --delete '\n'.
Elijah Lynn el
69

La salida de tubería a xargsconcatenará cada línea de salida en una sola línea con espacios:

grep pattern file | xargs

O cualquier comando, por ejemplo. ls | xargs. El límite predeterminado de xargssalida es ~ 4096 caracteres, pero se puede aumentar con, por ejemplo,. xargs -s 8192.

Bluebadge
fuente
| tr '\n' ' 'no funcionaba para mí cuando se llamaba a través de la php execfunción. Estaba ignorando tr, y solo daba el último partido de grep. | xargstrabajó.
Adarsha
3
Esta solución también tiene la ventaja de que 'come' espacios desde la entrada. +1
Rene
55

En bash echosin comillas, elimine retornos de carro, pestañas y espacios múltiples

echo $(cat file)
usuario1699917
fuente
8
Respuesta muy subestimada aquí, esto es realmente simple y funciona de maravilla, con una nueva línea final también.
Dangercrow
Esto es especialmente bueno si lo usaIFS="$(printf '\n\t')"
aggsol
55
O simplemente echo $(<file)... usar echo no solo es más ordenado que usar tr '\n' ' ', sino también mejor (piense en las \r\nterminaciones de línea). @aggsol, puedes decirIFS=$'\n\t'
Normadize
¿Qué tal sin espacio?
DimiDak
22

Esto podría ser lo que quieras

cat file | grep pattern | paste -sd' '

En cuanto a su edición, no estoy seguro de lo que significa, ¿tal vez esto?

cat file | grep pattern | paste -sd'~' | sed -e 's/~/" "/g'

(esto supone que ~no ocurre en file)

sehe
fuente
2
@Stephan no había necesidad de asumir que cat filerealmente será cat, o incluso un archivo. (Acabo de dejar esa parte sin cambios ya que era irrelevante para la pregunta)
sehe
5

Este es un ejemplo que produce resultados separados por comas. Puede reemplazar la coma por cualquier separador que necesite.

cat <<EOD | xargs | sed 's/ /,/g'
> 1
> 2
> 3
> 4
> 5
> EOD

produce:

1,2,3,4,5
Richard Gomes
fuente
3

Aquí está el método que usa el exeditor (parte de Vim ):

  • J oin todas las líneas y p rint a la salida estándar:

    $ ex +%j +%p -scq! file
  • J oin todas las líneas en el lugar (en el archivo):

    $ ex +%j -scwq file

    Nota: ¡Esto concatenará todas las líneas dentro del archivo!

kenorb
fuente
2

Las formas más rápidas y fáciles que conozco para resolver este problema:

Cuando queremos reemplazar el nuevo carácter de línea \n con el espacio :

xargs < file

xargstiene sus propios límites en la cantidad de caracteres por línea y la cantidad de todos los caracteres combinados, pero podemos aumentarlos. Los detalles se pueden encontrar ejecutando este comando: xargs --show-limitsy, por supuesto, en el manual:man xargs

Cuando queremos reemplazar un personaje con otro exactamente un personaje :

tr '\n' ' ' < file

Cuando queremos reemplazar un personaje con muchos personajes :

tr '\n' '~' < file | sed s/~/many_characters/g

Primero, reemplazamos los caracteres de nueva línea \npor tildes ~(o elegimos otro carácter único que no esté presente en el texto), y luego reemplazamos los caracteres de tilde con cualquier otro carácter ( many_characters) y lo hacemos para cada tilde (bandera g).

simhumileco
fuente
0

Probablemente la mejor manera de hacerlo es usar la herramienta 'awk' que generará resultados en una línea

$ awk ' /pattern/ {print}' ORS=' ' /path/to/file

Fusionará todas las líneas en una con delimitador de espacio

Vladimir Yahello
fuente
No es necesario {print}ya que es la acción predeterminada de awk.
rígido
0

Aquí hay otro método simple usando awk:

# cat > file.txt
a
b
c

# cat file.txt | awk '{ printf("%s ", $0) }'
a b c

Además, si su archivo tiene columnas, esto proporciona una manera fácil de concatenar solo ciertas columnas:

# cat > cols.txt
a b c
d e f

# cat cols.txt | awk '{ printf("%s ", $2) }'
b e
antepasados
fuente
-1

En Red Hat Linux solo uso echo:

echo $ (cat / some / file / name)

Esto me da todos los registros de un archivo en una sola línea.

usuario13498546
fuente
2
Esto, como ya se respondió en 2015. Solo está duplicando esta respuesta . Lea las respuestas antes de publicar las suyas, especialmente cuando la pregunta tiene 7 años y ya hay 8 respuestas.
Mickael B.