br sed: Removendo \ r \ r antes \ n em um arquivo muito grande

2

Eu tenho um arquivo de imagem de disco corrompido (cerca de 27 GB) no qual antes de todos os \ n caracteres \ r \ r serem inseridos. Desejo remover estes \ r \ r antes de todos \ n.

Eu tentei com o awk:

awk '{ sub("\r\r$", ""); print }' mangled.raw > image.raw

Mas o arquivo parece muito grande: "awk: erro de tempo de execução: sem memória"

Eu também tentei com o sed:

sed 's/\r\r$//g' mangled.raw > image.raw

Mas aqui o arquivo de saída parece incompleto: ele tem apenas 20 GB de tamanho e o final de mangled.raw contém muitos caracteres zero, enquanto o fim de image.raw contém o conteúdo de um arquivo. De alguma forma sed parece parar antes do final.

Alguma ideia de como fazer isso direito?

    
por Mel 18.03.2014 / 11:19

1 resposta

3

O comentário do idoso pode estar correto - depende de como a corrupção aconteceu. Se ele fez o equivalente a s/\n/\r\r\n/ , então é reversível, mas se ele fez s/\r*\n/\r\r\n/ então não é.

De qualquer forma, eu usaria o perl para algo assim. Ao contrário do sed, ele foi projetado desde o início para trabalhar com strings que são muito longas e podem conter NULs e outros caracteres que não são de texto.

perl -pe 's/\r\r\n/\n/g' mangled.raw > image.raw

Isso pode consumir muita memória, pois ainda está lendo o arquivo como uma série de linhas, e pode haver grandes segmentos do arquivo sem \n , que será visto como uma única "linha". Mas se você a ler por blocos, você deve ter cuidado para não perder uma seqüência de \r\r\n que atravessa um limite de bloco. Assim:

perl -e '
  $/=536;
  while(<>) {
    if(/\r\z/) {
      if(length($nextblock=<>)) {
        $_.=$nextblock;
        redo;
      }
    }
    s/\r\r\n/\n/g;
    print;
   }
' mangled.raw > image.raw

Edit: Eu percebi que o código acima ficaria preso em um loop infinito se o último byte da entrada fosse \r . Ele foi atualizado para lidar com esse caso corretamente.

Editar 2: O perl one-liner continha um caractere de substituição incorreto. Ele foi atualizado.

    
por 18.03.2014 / 13:21

Tags