例如,我有一个大(~180MB)的 xml 文件,其中包含一些错误的字符
<Data ss:Type="String">7402953^@</Data>
该^@
部件应被移除。这项工作应该完成
sed -i 's/\^@//g' /tmp/large.xml
但由于某种未知的原因,如果字符串位于我的大 xml 文件中,它就无法按预期工作。如果文件大小只有几 KB,则sed
可以正常工作。
它看起来像一个错误,但我认为不可能,因为任务非常明显。我做错了什么吗?
答案1
从你的问题来看(因为没有例子),我想说^@
在大文件中实际上并不是两个字符(^
和@
),而是那些不可打印的字符之一。
Ctrl + v
您可以使用+在终端中输入该不可打印的字符Ctrl + 2
。
用它来sed
代替字符^
,@
应该没问题。
还要删除转义序列,因为不可打印字符不需要它。
答案2
awk
如果使用的解决方案awk
可以接受,这将删除所有不可打印的字符。
这适用于 GNU awk (Linux) 和 BSD awk (Mac)。
awk '{ gsub(/[^[:print:][:blank:]]/,"",$0) ; print $0 }' input.xml > output.xml
gsub(/[^[:print:][:blank:]]/,"",$0)
从输入的每一行中删除任何不需要的字符。[:print:]
任何可打印字符。[:blank:]
空格或制表符。[^[:print:][:blank:]]
不包含在这两个类别中的任何角色。
print $0
打印输入的每一行。> output.xml
将输出保存到文件中,而不是将其打印到屏幕上。
用更少的击键来做同样的事情(只是阅读起来有点困难):
awk '{gsub(/[^[:print:][:blank:]]/,"")}1' input.xml > output.xml
- 如果您正在检查整行,则不需要指定
,$0
(整行输入) 。gsub
- 最后的意思
1
是“现在对每一行执行默认操作(即打印)”。