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

问题描述 投票:1回答:5

我需要从文件中删除一些未知字符和剩余的空行,它应该很简单,我感觉非常愚蠢,我还不能这样做。

这是文件内容(可读):

    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)

出于某种原因,此文件附带了几个不需要/未知的字符。 HEX是:

    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...........

因此,正如您所看到的,前两个字节是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)中提取的。

由于新文件可能不是这样并且作为普通文本文件到达,我不能简单地剪切文件,但我需要对待那些有问题的人。

shell awk sed hex tr
5个回答
1
投票

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

在另一个stackoverflow问题/答案中,文件首先转换为UTF-8 ...(qazxsw poi)


1
投票

我终于做到了,但真的不喜欢这个解决方案。我已经用管道(grepping binary files and UTF16)替换了所有换行符,然后当我在序列中找到两个(|)时将其删除,然后将管道(||)转换回|

\n

- @Luciano


0
投票

如果您只想从文件中删除ASCII字符,可以尝试使用sed 's/\xFF\xFE//g; s/\x00//g; s/\x0D//g' 2014.log | tr '\n' '|' | sed 's/||//g;' | sed 's/|/\x0A/g' > 5.log

您可以使用iconv识别文件的编码


0
投票

我知道你要求file -isedtr,但是它会改变你的想法,这就是让Perl做繁重的事情是多么容易:

awk

0
投票

哇我当时解决了这个问题,但忘了回答,所以在这里!

只使用tr命令我可以像这样完成:

tr -d'\ 377 \ 376 \ 015 \ 000 \ 277 \ 003'<logs.csv | tr -s'\ n'

tr删除了所有不需要的字符和空行,它真的,非常快,比使用sed和awk的选项快得多

© www.soinside.com 2019 - 2024. All rights reserved.