Como deletar linhas “undeletable” no Vi?

4

Plano de fundo

Eu apaguei acidentalmente um script python importante e, por isso, executei o comando

sudo grep --binary-files=text --context=100 'unique string' /dev/sda1 > recover_file

para procurá-lo no meu disco rígido e salvar as correspondências em ./recover_file . Quando eu abro ./recover_file em Vi ("Vi Unimproved", não Vim) eu vejo que ele tem ~ 10800 linhas e contém muitas versões do meu arquivo de 200 ~ linhas, com algum lixo entre cada ocorrência, como esperado. Mas também há centenas de linhas estranhas com comportamento inesperado que tentarei descrever.

Eu tenho números de linha. Se a linha 19 for a primeira linha estranha no arquivo, ao abrir o arquivo, recebo uma mensagem na parte inferior da janela dizendo

Conversion error on line 19

Inicialmente, as linhas estranhas aparecem como linhas vazias, como as linhas exibidas na parte inferior de um documento quando não há mais linhas no arquivo a ser exibido, com um caractere ~ na extremidade esquerda da janela, mas localizado entre duas outras linhas, não no final do arquivo:

    18 junk junk junk
~
    20 junk junk junk

Quando tento excluir a linha 19 usando dd , nada acontece. Se eu excluir uma linha normal, a aparência da linha 19 mudará e parecerá com qualquer outra linha em branco:

    18 junk junk junk
    19
    20 junk junk junk

Mas assim que eu movo meu cursor sobre ele, o número da linha desaparece e parece exatamente como antes. Se eu tentar executar alguma operação, como inserir ou anexar texto, recebo

Error: unable to retrieve line 19

Se eu gravar o arquivo no disco, obtenho

Error: recover_file: Invalid or incomplete multibyte or wide character.
recover_file: WARNING: FILE TRUNCATED.

Então, se eu fechar e reabrir o arquivo, vejo que todas as linhas de 19 em diante foram removidas, deixando apenas as linhas 1-18. Consegui reproduzir a situação e copiar uma versão recente do arquivo python para um novo arquivo, após o qual investigar ainda mais ./recover_file produziu uma falha de segmentação e o arquivo inteiro foi perdido.

Perguntas

1) Para referência futura, existe uma maneira de remover essas linhas estranhas para que eu possa salvar o arquivo diretamente sem perder dados importantes, ou sempre precisarei destacar e copiar da janela do terminal?

2) Eu assumo que esse comportamento é devido à presença de código binário em ./recover_file não correspondente a caracteres de texto, que Vi não pode renderizar. Se alguém pudesse confirmar / corrigir essa impressão e talvez fornecer mais explicações, eu ficaria grato.

Atualizar

Não tenho certeza se isso é relevante, mas estou executando o lubuntu 18.04 como uma máquina virtual no VMware Workstation 14 Player.

    
por The Ledge 19.07.2018 / 18:42

1 resposta

4

Ao olhar para o seu script, você está descarregando e tentando editar, pesquisar e editar linhas, arquivos binários com o editor de texto vi .

Dessa forma, você encontrará muitos caracteres de controle que subverterão a noção de linhas, o comprimento das linhas e, em algumas situações, até mesmo o fim do arquivo.

Como você está interessado apenas em texto e já está analisando o conteúdo do disco, eu adicionaria um comando strings para descartar caracteres que não são de texto.

Para conseguir manipular sua saída no vi, você pode alterar seu script para:

sudo grep --binary-files=text --context=100 'unique string' /dev/sda1 | strings > recover_file

Eu também suspeito que será mais eficiente descartar esses caracteres de controle para começar, como em:

sudo strings /dev/sda1 | grep --context=100 'unique string' > recover_file

Embora eu não esteja inteiramente certo de que esta última instrução tenha os mesmos resultados por ser tratada como texto e não como binária.

De man strings

strings - print the strings of printable characters in files.

Description

For each file given, GNU strings prints the printable character sequences that are at least 4 characters long (or the number given with the options below) and are followed by an unprintable character. By default, it only prints the strings from the initialized and loaded sections of object files; for other types of files, it prints the strings from the whole file.

    
por 20.07.2018 / 09:36