Remover caracteres de fim de linha do stdout? Várias linhas em uma única linha

14

Eu tenho um script que gera o seguinte texto. Essa é a saída de um modem Netopia 2210-02 ADSL2 .

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

Como posso remover o caractere de fim de linha de cada linha? Gostaria que a saída se parecesse com algo assim (Sim, é feio):

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 

Eu tentei algumas soluções como esta, mas elas não funcionam:

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

Eu também tentei usar tr. Eu estava esperando o seguinte comando para substituir cada caractere de nova linha pelo caractere de espaço. Isso pegaria as várias linhas e as combinaria em uma única linha longa. Em vez disso, isso exibe apenas a última linha de saída. Parece substituir cada linha subseqüente pela próxima linha de saída.

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

Atualização :

Após um exame mais aprofundado, parece que cada linha é precedida por um caractere de retorno. Isso aparece como ^Mao usar less. Então, eu adicionei duas trdeclarações. Um para excluir caracteres de nova linha, um para excluir o caractere de retorno.

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

Respostas:

18

sednão funcionará (facilmente) porque opera nas linhas uma por vez; você poderia fazer isso, mas isso envolveria copiar toda a entrada no buffer de retenção

trrealmente deve funcionar da maneira que você colou; tem certeza de que as novas linhas são \ns? Você pode simplificá-lo um pouco, excluindo as novas linhas em vez de convertê-las em espaços:

tr -d '\n'
Michael Mrozek
fonte
Ambos tr '\n' ' 'e tr -d '\n' vão quebrar a linha de uma maneira estranha. Atualizei minha pergunta para mostrar os resultados. Então, talvez eu precise usar tr, mas só preciso descobrir como usá-lo corretamente.
Stefan Lasiewski
Você poderia expandir o que é estranho? O motivo pelo qual o prompt está terminando na mesma linha que a última linha de saída é precisamente porque você removeu o '\ n' no final da linha. Se você descrever o resultado final que deseja, tenho certeza de que alguém criará o filtro apropriado.
Steven D
Ok, acho que poderia ser mais claro. Eu esperava agrupar essas várias linhas em uma única linha. Eu esperaria tr '\n' ' 'remover o caractere de nova linha e substituí-lo por um caractere de espaço e, portanto, ter uma linha longa.
Stefan Lasiewski
@ Steven: Atualizei minha pergunta para discutir o que eu esperava ver e o que realmente estava impresso na tela.
Stefan Lasiewski
Hmm. A menos que sua saída não termine com \ n, isso deve fornecer a saída que você espera. Você já tentou inseri-lo em um arquivo e depois confirmar que a quebra de linha não é algo que seu termo está fazendo por você?
Steven D
5

além disso tr, alguns outros métodos que você pode usar

awk

awk '1' ORS= file

Concha

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

sed

sed -e ':a' -e 'N;s/\n/ /;ba' file
user1606
fonte
0

Use tr -s '\n'para substituir seqüências de caracteres de nova linha repetidos por uma única ocorrência de nova linha.

Exemplo:

>>> 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
fonte
0

Para remover caracteres de nova linha, é tr -d '\n' < file. No entanto, para juntar todas as linhas, é isso paste -sd '\0' file.

tr -d '\n' produz saída não textual, pois não termina a linha com um caractere de nova linha.

Para remover todos os caracteres CR, você pode:

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

Para remover apenas os caracteres CR que estão no final das linhas:

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

Ou use awkpara tudo:

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

Ou use dos2unix(o que removeria os CRs à direita e também corrigiria outros problemas com os arquivos de texto dos sistemas operacionais Microsoft):

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