Substitua dois CR consecutivos por um

Substitua dois CR consecutivos por um

cat -e file.txtdá:

{"yellow":"mango"}^M$
^M$
{"yellow":"banana"}^M$
^M$
{"yellow":"blabla"}^M$
^M$

e eu gostaria apenas de ter:

{""yellow":"mango"}^M$
{"yellow":"banana"}^M$
{"yellow":"blabla"}^M$

em vigor para todos os arquivos com extensão txt na pasta. Então eu tentei:

find . -type f -name "*.txt" -print0 | xargs -0 sed -i "s/^M$^M$/^M$/g"

para nenhum proveito. Alguém tem uma idéia melhor?

head -n 3 file.txt | od -bc

rendimentos:

0000000 173 042 171 145 154 154 157 167 042 072 042 155 141 156 147 157
          {   "   y   e   l   l   o   w   "   :   "   m   a   n   g   o
0000020 042 175 015 012 015 012 173 042 142 141 142 141 142 042 072 042
          "   }  \r  \n  \r  \n   {   "   b   a   b   a   b   "   :   "
0000040 155 141 156 147 157 042 175 015 012
          m   a   n   g   o   "   }  \r  \n
0000051

esse:

awk 1 RS='\r\n' ORS= < file.txt

remove completamente as novas linhas (então não é bom: quero manter uma das duas sucessivas em cada linha, mas faz alguma coisa).

Responder1

Você pode usar sed -z 's/\r\n\r\n/\r\n/g'.

Normalmente sedsó funciona em uma linha por vez. Ao usar a -zopção, sedfuncionará em linhas, que são separadas por 0bytes, que normalmente não existem em um arquivo de texto, portanto todo o arquivo será tratado como uma linha e novas linhas poderão ser substituídas.

(encontrado emfluxo de pilhae explicação adicional)

Responder2

Você também pode excluir linhas que contenham apenas o retorno de carro.

  • Com GNU Sed:

    sed '/^\r$/d' file
    
  • Para uma máquina mínima, mas compatível com POSIX (aqui precisamos gerar o retorno de carro com Printf):

    sed "/^$(printf "\r")$/d" file
    

^corresponde ao início da linha e o último $, ao final da linha ( \n).

Por exemplo:

$ cat -e file
AB^M$
^M$
CB^M$
^M$
$ sed '/^\r$/d' file|cat -e
AB^M$
CB^M$

Responder3

Se não houver problema em remover todas as linhas em branco, você pode fazer:

perl -wlne '/\S/ and print' old_file > new_file

E se preferir sobrescrever seu(s) arquivo(s), você pode usar a -iopção (in-loco):

perl -wlni.bak -e '/\S/ and print' file1 file2 file3 ...

A linha acima copiará os arquivos originais como *.bakarquivos. Se você não se importa em ter backups, basta deixar de fora uma .bakparte, assim:

perl -wlni -e '/\S/ and print' file1 file2 file3 ...

(Você pode até usar curingas, então em vez de file1 file2 file3 ...escrever file*.)

A vantagem dessa abordagem é que ela faz alterações nos arquivos de uma só vez (em vez de ter que executá-la uma vez para cada arquivo).

Mas lembre-se: isso manterá apenas as linhas que contenham pelo menos um caractere que não seja um espaço em branco. Portanto, se uma linha consistir apenas em cinco espaços, uma tabulação, um retorno de carro e um caractere de avanço de linha, ela não será mantida.

Responder4

Usando Raku (a linguagem anteriormente conhecida como Perl6)

~$ raku -ne '.put if /\S/ ;' test_blank.txt
{"yellow":"mango"}
{"yellow":"banana"}
{"yellow":"blabla"}

O exemplo acima imprime apenas linhas que contêm caracteres que não são espaços em branco ( \Scorresponde a um único caractere que não é espaço em branco). Uma versão bem legível abaixo:

~$ raku -ne '.put if .chars;' test_blank.txt
{"yellow":"mango"}
{"yellow":"banana"}
{"yellow":"blabla"}

HTH.

https://raku.org
https://rakudo.org/downloads

informação relacionada