显示并删除所有字符> ascii代码127


2

如何从文件中显示和删除所有字符> ascii代码127?

文件是unicode 16bit

更新丹尼斯解决了它,但有一些有关数字范围的有趣讨论。


你为什么需要那个?
grawity 2011年

@gravvity你为什么这么问?
barlop 2011年

因为它会影响你的行为方式。另一个问题:您是否通过Cygwin或GNUWin32或类似工具提供Unix风格的工具?
丹尼斯威廉姆森

@Dennis Williamson我对许多选择持开放态度。我有Cygwin和Gnuwin32,通过那些做它很好,但问题是我的文件是unicode 16bit。我注意到这一行:cat | od -c解释每个char之间的\ 0,并且grep不起作用因为grep看到的字母abc不是连续的,可能是因为相同的原因。他们假设每个字符8位。
barlop 2011年

由于你有一个Unicode文件,你应该知道这是真正的重要原因,我要求提供更多信息。从Unicode文件中删除带字节值的字节(请注意我没有说“字符”和“ASCII代码”)会产生奇怪的结果。你真的想做什么?
丹尼斯威廉姆森

Answers:


1

一种方法是将文件转换为十六进制数字,删除您不想要的数字模式,然后转换回来。

$ echo 'A Unicode character: [ñ]' | xxd -p | sed 's/c3b1//' | xxd -r -p
A Unicode character: []

您可以使用AWK或任何其他文本操作技术代替sed。注意模棱两可的序列。

如果这接近您的想法,请告诉我。


是的,这接近我的想法
barlop 2011年

从那里我可以看到我怎么可能这样做.. od -x myfile | 切换到开始时超过FEFF,在sed中捕获十六进制范围内的正则表达式中的对。
barlop 2011年

实际上,我的想法不会削减它..但是是的,可以让我看到十六进制的程序或集合的想法,在十六进制上使用正则表达式并将其写回来是我想到的一种通用方法..我有兴趣看看你如何调整它的要求。如果有任何问题,欢迎您发布其他方法草图。如果不是太麻烦的话。我会感兴趣,我觉得它很有用。
barlop 2011年

我实际上通过你给的那个草图到达那里,并且使用剪切,我错过了它之前的tr -d'\ n'..
barlop 2011年

实际上我一直试图调整你的草图。你的草图很好(当然你知道!)但是我的调整就是问题所在。'我知道之后| tr -d'\ n'然后剪切5-,这有效,我不想只扫描说FEFF或[8-F] [0-F] [0-F] [0-F]因为我不想重叠2个字符的字节。无论我在sed s的find部分放了什么。因此,如果我尝试匹配每个字节对,那么它将删除该批次。并且我不确定如何或者是否可以使用sed有条件地替换字节对。
barlop 2011年

0

回头看这个问题

看起来我最终使用了其中一条线

(似乎是丹尼斯的正则表达式)

$ xxd -p a.q | tr -d '\n' | sed "s/([0-9a-f]\{4\})/\1 /g" | sed -r "s/(00[8-9a-f][0-9a-f]|[0-9a-f][1-9a-f][0-9a-f][0-9a-f]|[1-9a-f]0[0-9a-f][0-9a-f])//g" | tr -d ' ' | sed "s/(.*)/feff\1/" | xxd -r -p >a.q2

或者这(似乎是我的正则表达式)

$ xxd -p a.q | tr -d '\n' | sed "s/([0-9a-f]\{4\})/\1 /g" | sed -r "s/(00[89A-F][0-9A-F]|0[1-9A-F][0-9A-F]{2}|[1-9A-F][0-9A-F]{3})//g" | tr -d ' ' | sed "s/(.*)/feff\1/" | xxd -r -p >a.q2

这是关于我如何解决这个问题的一些评论。

0080-00FF     00[89A-F][0-9A-F]
0100-0FFF     0[1-9A-F][0-9A-F]{2}
1000-FFFF     [1-9A-F][0-9A-F]{3}

这里有一些测试表明正则表达式有效。当我解决它时,我已将它们置于我的问题中,但我应该将它们放入答案中。

总十六进制字符85

$ xxd -u -p a.aa.txt | sed -r "s/.{4}/\0 /g" | grep -oE "[0-9A-F]{4}" | wc -l
85

我想要的总数,72

$ xxd -u -p a.aa.txt | sed -r "s/.{4}/\0 /g" | grep -oE "00[0-7][0-F]" | wc -
l
72

我不想要的总数,13

$ xxd -p -u a.aa.txt | sed -r "s/[0-9A-F]{4}/\0 /g" | grep -oP '((?!00[0-7][0-9A-F])(?=[^ ]).){4}' | wc -l
13

我不想要的总数,13

$ xxd -u -p a.aa.txt | sed -r "s/.{4}/\0 /g" | grep -oE "00[89A-F][0-9A-F]|0[1-9A-F][0-9A-F]{2}|[1-9A-F][0-9A-F]{3}" | wc –l
13

现在看着它我想知道为什么我不只是grep我想要保持的unicode十六进制字符在这个测试中$ xxd -u -p a.aa.txt | sed -r "s/.{4}/\0 /g" | grep -oE "00[0-7][0-F]" 而不是替换那些我不想保留的东西。(后者相当于一个更长的正则表达式)
barlop 2014年

顺便说一句,第一个xxd -p aq行在dennis的注释中使用正则表达式,第二个使用我想出的正则表达式。
barlop 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.