shell - 使用 SED、TR 或/和 awk 删除不需要的字符和空行

标签 shell awk sed hex tr

我需要从文件中删除一些未知字符和剩余的空行,这应该很简单,但我觉得自己真的很愚蠢,我还做不到。

这是文件内容(可读):

    136;2014-09-07 13:41:25;2014-09-07 13:41:55
    136;2014-09-07 13:41:55;2014-09-07 13:42:25
    136;2014-09-07 13:42:25;2014-09-07 13:42:55
    (empty line)
    (empty line)

由于某种原因,此文件带有几个不需要的/未知的字符。十六进制是:

    fffe 3100 3300 3600 3b00 3200 3000 3100 3400 2d00 3000 3900  :..1.3.6.;.2.0.1.4.-.0.9.
    2d00 3000 3700 2000 3100 3300 3a00 3400 3100 3a00 3200 3500  :-.0.7. .1.3.:.4.1.:.2.5.
    3b00 3200 3000 3100 3400 2d00 3000 3900 2d00 3000 3700 2000  :;.2.0.1.4.-.0.9.-.0.7. .
    3100 3300 3a00 3400 3100 3a00 3500 3500 0d00 0a00 3100 3300  :1.3.:.4.1.:.5.5.....1.3.
    3600 3b00 3200 3000 3100 3400 2d00 3000 3900 2d00 3000 3700  :6.;.2.0.1.4.-.0.9.-.0.7.
    2000 3100 3300 3a00 3400 3100 3a00 3500 3500 3b00 3200 3000  : .1.3.:.4.1.:.5.5.;.2.0.
    3100 3400 2d00 3000 3900 2d00 3000 3700 2000 3100 3300 3a00  :1.4.-.0.9.-.0.7. .1.3.:.
    3400 3200 3a00 3200 3500 0d00 0a00 3100 3300 3600 3b00 3200  :4.2.:.2.5.....1.3.6.;.2.
    3000 3100 3400 2d00 3000 3900 2d00 3000 3700 2000 3100 3300  :0.1.4.-.0.9.-.0.7. .1.3.
    3a00 3400 3200 3a00 3200 3500 3b00 3200 3000 3100 3400 2d00  ::.4.2.:.2.5.;.2.0.1.4.-.
    3000 3900 2d00 3000 3700 2000 3100 3300 3a00 3400 3200 3a00  :0.9.-.0.7. .1.3.:.4.2.:.
    3500 3500 0d00 0a00 0000 0d00 0a00                           :5.5...........

因此,正如您所看到的,前 2 个字节是 xFF 和 xFE,每个字符后面有许多 x00。行结尾是 0D00 + 0A00、回车符和换行符 (\r\n) 加上 x00 的连接。

我想删除那些 x00 和前 2 个字节 xFFxFE 以及最后 4 个字节,并将 CRLF 转换为 LF

我可以通过使用 head、tail 和 tr 来做到这一点:

    tr -d '\15\00' < 2014.log | tail -c +3 | head -c -2 > 3.log

问题是,我不确定文件是否总是这样到达,所以我需要构建一个更通用的方法。我最终得到:

    sed 's/\xFF\xFE//g; s/\x00//g; s/\x0D//g' 2014.log > 2.log
    or
    tr -d '\377\376\00\15' < 2014.log > 2.log

现在我需要删除最后两行空行,正如我在一开始所说的那样,这应该很容易,但我无法做到这一点。

我已经尝试过:

    sed '/^\s*$/d'
    sed '/^$/d'
    awk 'NF > 0'
    egrep -v "^$"
    Other stuff

但最后它只删除了一个空行,我最后仍然有一个x0A。我尝试用 sed 替换两个 x0Ax0A 的连接,甚至使用\n\n 但它不起作用。 我无法删除所有 \n 因为我需要正常的行,我只想在它们按顺序出现至少两次时删除。我再次可以使用 tail 或 head 来删除它,但我假设所有文件都会以这种方式到达,但事实并非如此。

我将其视为简单的查找和替换内容,但当我们使用换行符时,它似乎不起作用。

仅供引用:

    file -i 2014-09-07-13-46-51.log
    2014-09-07-13-46-51.log: application/octet-stream; charset=binary

它未被识别为文本文件...此文件是从 Flash 共享对象 (.sol) 中提取的。

由于新文件可能不是这样的,而是作为普通文本文件到达的,所以我不能简单地剪切文件,但我需要处理那些有问题的文件。

最佳答案

文件开头的“fffe”是一个字节顺序标记( http://en.wikipedia.org/wiki/Byte_order_mark ),对我来说,这表明您有一个 unicode 类型文件。在这种文件中,“正常”ascii 字符由 2 个字节表示。

在另一个 stackoverflow 问题/解答中,文件首先转换为 UTF-8... ( grepping binary files and UTF16 )

关于shell - 使用 SED、TR 或/和 awk 删除不需要的字符和空行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25748260/

相关文章:

使用 sed 命令从文本文件中提取字符串

java - OSX 上的文件关联,用于不使用 JavaStub 的 Java 应用程序包

bash - 将列表转为表格格式 (awk)

正则表达式在 Shell 中查找和替换多行

sed - 使用 sed 删除文件的行 - 意外行为

bash - 不带引号的 Heredoc 不扩展参数

awk - sed 或 awk : group by paragraphs consisting of 2nd upto n+1th lines of each paragraph

for-loop - 对列的值逐行求和

linux - sed 编辑 yaml 文件,其中每个键都有单独的值

linux - 使用超时命令时如何获取文件中的日志?