如何删除 Vi 中“不可删除”的行?

如何删除 Vi 中“不可删除”的行?

背景

我不小心删除了一个重要的python脚本,所以我运行了命令

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

在我的硬盘上搜索它并将匹配项保存到./recover_file.当我./recover_file在 Vi(“Vi Unimproved”,而不是 Vim)中打开时,我看到它大约有 10800 行长,并且包含大约 200 行文件的许多版本,正如预期的那样,每次出现之间都有一些垃圾。但也有数百条奇怪的线路具有意想不到的行为,我将尝试描述它们。

我有行号。如果第 19 行是文件中的第一个奇怪的行,则在打开文件时我会在窗口底部收到一条消息:

Conversion error on line 19

最初,这些奇怪的行显示为空行,就像当文件中没有更多行要显示时显示在文档底部的行,~在窗口的最左边缘有一个字符,但位于其他两行之间,不在文件末尾:

    18 junk junk junk
~
    20 junk junk junk

当我尝试使用 删除第 19 行时dd,没有任何反应。如果我删除普通行,则第 19 行的外观会发生变化,它看起来就像任何其他空白行:

    18 junk junk junk
    19
    20 junk junk junk

但是当我将光标移到它上面时,行号就消失了,看起来就像以前一样。如果我尝试对其执行任何操作,例如插入或附加文本,我会得到

Error: unable to retrieve line 19

如果我将文件写入磁盘,我会得到

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

然后,如果我关闭并重新打开该文件,我会看到从 19 行开始的所有行都已被删除,只留下 1-18 行。我能够重现这种情况,并将最新版本的 python 文件复制到一个新文件中,之后进一步挖掘./recover_file产生了分段错误,整个文件丢失了。

问题

1)为了将来参考,有没有办法可以删除这些奇怪的行,以便我可以直接保存文件而不会丢失重要数据,或者我总是需要突出显示并从终端窗口复制?

2)我认为这种行为是由于二进制代码的存在与./recover_file文本字符不对应,而Vi无法呈现。如果有人可以确认/纠正这种印象,并可能提供进一步的解释,我将不胜感激。

更新

我不确定这是否相关,但我正在 VMware Workstation 14 Player 上将 lubuntu 18.04 作为虚拟机运行。

答案1

通过查看您的脚本,您正在转储并尝试使用vi文本编辑器编辑、搜索和行编辑二进制文件。

这样,您将遇到许多控制字符,它们将颠覆行、行长度的概念,在某些情况下,甚至可能颠覆文件结尾的概念。

由于您只对文本感兴趣,并且您已经在某种程度上解析磁盘内容,因此我将strings向其添加一个命令以丢弃非文本字符。

为了能够在 vi 中处理输出,您可以将脚本更改为:

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

我还怀疑一开始就丢弃这些控制字符会更有效,如下所示:

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

尽管我不完全确定最后一条指令会给出相同的结果,因为它是作为文本而不是二进制处理的。

man strings

strings - 打印文件中可打印字符串。

描述

对于给定的每个文件,GNU 字符串打印至少 4 个字符长(或通过以下选项给出的数字)的可打印字符序列,后跟一个不可打印的字符。默认情况下,它仅打印目标文件的初始化和加载部分中的字符串;对于其他类型的文件,它会打印整个文件中的字符串。

相关内容