我需要从文件中删除一些未知字符和剩余的空行,它应该很简单,我感觉非常愚蠢,我还不能这样做。
这是文件内容(可读):
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
)中提取的。
由于新文件可能不是这样并且作为普通文本文件到达,我不能简单地剪切文件,但我需要对待那些有问题的人。
文件开头的“fffe”是字节顺序标记(http://en.wikipedia.org/wiki/Byte_order_mark),对我来说是一个unicode类型文件的指示。在那种文件中,“正常”ascii字符由2个字节表示。
在另一个stackoverflow问题/答案中,文件首先转换为UTF-8 ...(qazxsw poi)
我终于做到了,但真的不喜欢这个解决方案。我已经用管道(grepping binary files and UTF16)替换了所有换行符,然后当我在序列中找到两个(|
)时将其删除,然后将管道(||
)转换回|
\n
- @Luciano
如果您只想从文件中删除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识别文件的编码
我知道你要求file -i,sed
或tr
,但是它会改变你的想法,这就是让Perl做繁重的事情是多么容易:
awk
哇我当时解决了这个问题,但忘了回答,所以在这里!
只使用tr命令我可以像这样完成:
tr -d'\ 377 \ 376 \ 015 \ 000 \ 277 \ 003'<logs.csv | tr -s'\ n'
tr删除了所有不需要的字符和空行,它真的,非常快,比使用sed和awk的选项快得多