¿Eliminar los caracteres de final de línea de stdout? Múltiples líneas en una sola línea.

14

Tengo un script que genera el siguiente texto. Esta es la salida de un módem ADSL2 Netopia 2210-02 .

ADSL Line State:        Up
ADSL Startup Attempts:  1
ADSL Modulation:        DMT
ADSL Data Path:         Fast
Datapump Version:       DSP 7.2.3.0, HAL 7.2.1.0
SNR Margin:                   8.20        9.00 dB
Line Attenuation:            57.50       31.00 dB
Output Power:                17.09       12.34 dBm
Errored Seconds:                 0           0
Loss of Signal:                  0         476
Loss of Frame:                   0           0
CRC Errors:                  57921         416
Data Rate:                    2880        1024

¿Cómo puedo eliminar el carácter de fin de línea para cada línea? Me gustaría que la salida se vea así (Sí, es feo):

ADSL Line State:        Up ADSL Startup Attempts:  1 ADSL Modulation:        DMT ADSL Data Path:         Fast Datapump Version:       DSP 7.2.3.0, HAL 7.2.1.0 SNR Margin:                   8.20        9.00 dB Line Attenuation:            57.50       31.00 dB Output Power:                17.09       12.34 dBm Errored Seconds:                 0           0 Loss of Signal:                  0         476 Loss of Frame:                   0           0 CRC Errors:                  57921         416 Data Rate:                    2880        1024 

Intenté algunas soluciones como esta, pero no funcionan:

# (This simply outputs the contents of the script, unmodified)
stefanl@hosta:~/Work/Cacti $ ./script | sed -e 's/$//'

También intenté usar tr. Esperaba que el siguiente comando reemplazara cada carácter de nueva línea con el carácter de espacio. Esto tomaría las líneas múltiples y las combinaría en una sola línea larga. En cambio, esto solo muestra la última línea de salida. Parece sobrescribir cada línea posterior con la siguiente línea de salida.

stefanl@hosta:~/Work/Cacti $ ./script | tr '\n' ' '
Data Rate:                    2880        1024stefanl@hosta:~/Work/Cacti $
stefanl@hosta:~/Work/Cacti $

Actualización :

Tras un examen más detallado, parece que cada línea está precedida por un carácter de retorno. Esto aparece como ^Mcuando se usa less. Entonces, agregué dos trdeclaraciones. Uno para eliminar caracteres de nueva línea, uno para eliminar el carácter de retorno.

./script | | tr -d '\n' | tr -d '\r'
Stefan Lasiewski
fuente

Respuestas:

18

sedno funcionará (fácilmente) porque opera en líneas una a la vez; podría hacerlo, pero implicaría copiar toda la entrada en el búfer de retención

tren realidad debería funcionar como lo pegaste; ¿estás seguro de que las nuevas líneas son \ns? Puede simplificarlo un poco eliminando las nuevas líneas en lugar de convertirlas en espacios:

tr -d '\n'
Michael Mrozek
fuente
Ambos tr '\n' ' 'y tr -d '\n' envolverán la línea de una manera extraña. Actualicé mi pregunta para mostrar los resultados. Entonces, tal vez necesito usarlo tr, pero solo necesito descubrir cómo usarlo correctamente.
Stefan Lasiewski
¿Podrías ampliar lo que es extraño? La razón por la cual su mensaje termina en la misma línea que la última línea de salida es precisamente porque ha eliminado el '\ n' al final de la línea. Si describe el resultado final que está buscando, estoy seguro de que alguien encontrará el filtro adecuado.
Steven D
Ok, supongo que podría ser más claro. Esperaba envolver estas múltiples líneas en una sola línea. Esperaría tr '\n' ' 'eliminar el carácter de nueva línea y reemplazarlo con un carácter de espacio, y por lo tanto tener una línea larga.
Stefan Lasiewski
@ Steven: Actualicé mi pregunta para analizar lo que esperaba ver y lo que realmente se imprimió en la pantalla.
Stefan Lasiewski
Hmm A menos que su salida no termine con \ n, esto debería proporcionarle la salida que espera. ¿Has intentado ponerlo en un archivo y luego confirmar que el ajuste de línea no es algo que tu término está haciendo por ti?
Steven D
5

además tr, algunos otros métodos que puedes usar

awk

awk '1' ORS= file

cáscara

while read -r line; do printf "%s " "$line"; done <file

sed

sed -e ':a' -e 'N;s/\n/ /;ba' file
usuario1606
fuente
0

Se usa tr -s '\n'para reemplazar secuencias de caracteres de nueva línea repetidos con una sola aparición de nueva línea.

Ejemplo:

>>> echo -e "Squeeze\n\n\nthose\n\n\n\nnewlines\n"
Squeeze


those



newlines

2z [franck:~] $ 
>>> echo -e "Squeeze\n\n\nthose\n\n\n\nnewlines\n" | tr -s '\n'
Squeeze
those
newlines

(ver man tr)

Franck
fuente
0

Para eliminar caracteres de nueva línea, es tr -d '\n' < file. Sin embargo, para unir todas las líneas, eso es paste -sd '\0' file.

tr -d '\n' produce una salida sin texto ya que no termina la línea con un carácter de nueva línea.

Para eliminar, todos los caracteres CR, puede hacer:

tr -d '\r' < file | paste -sd '\0' -

Para eliminar solo los caracteres CR que están al final de las líneas:

CR=$(printf '\r')
sed "s/$CR\$//" < file | paste -sd '\0' -

O úsalo awkpara todo:

awk '{gsub(/\r$/, ""); printf "%s", $0} 
     END {if (NR) print ""}' < file

O use dos2unix(que eliminaría los CR finales y también solucionaría otros problemas con los archivos de texto de los sistemas operativos de Microsoft):

 dos2unix < file | paste -sd '\0' -
Stéphane Chazelas
fuente