我正在处理用意大利语和中文编写的文本,我需要使用仅提取中文字符AWK
。我怎样才能做到这一点?
我试过:
[中文 Unicode 字符的范围4E00 thru 9FFF (344 270 200 thru 351 277 277)
因此测试应该是>"\343" and <"\352"
(以避免拾取任何 4 个字符的 UTF-8 代码)]:
{
f=0;
for ( i=1; i<=length; i++)
if(substr($0, i, 1)>"\343" &&substr($0, i, 1)<"\352")
f = 1
print $f
}
但有一个错误或更多错误。我找不到它/他们
答案1
您的问题是,通过过滤 UTF-8 字符流中的原始字节,您会吃掉 UTF-8 文件中 unicode 序列的一部分,从而导致无效的字节序列。那是行不通的。相反,您需要使用理解 UTF-8 的工具,并对 unicode 数据(而不是原始字节)应用过滤器。
由于我不知道awk
你使用的是哪种实现,所以我无法判断它是否支持 unicode。但是,我知道 perl 是完全 unicode 安全的,因此以下 perl 单行代码应该可以工作:
perl -CS -p -e 's/[^\s\p{Han}]//g'
用于\s
空白,我假设您会想看到。该\p{Han}
位告诉 perl 我们想要匹配在 Unicode 中声明为用于汉字的字符(即中文字符)。我不知道您是否需要任何不包含在该范围内的标点符号;如果这样做,您可能还需要添加它。
然后我们用开头的 来否定范围^
,最后将其编码在全局替换命令 ( s///g
) 中,我们告诉 perl 替换第一个斜杠后面部分的实例(我们的否定范围,或者“不在这个范围内的所有内容” )与第二个之后和第三个之前的部分(即没有)。
如果不需要包含多个范围,则可以放弃[^]
构造,并切换到 using \P
not \p
,这会执行相同的匹配反转。
剩下的是我们输入的字符范围——汉字中的 unicode 字符,加上空格。
有关更多信息,请参阅perldoc perlre
有关 perl 如何处理正则表达式的解释,以及perldoc perluniprops
可能的 unicode 属性列表(可以放置在\p{}
or\P{}
构造中的位)。
答案2
使用awk
你可以这样做:
awk '{for(i=1; i<=length;i++) if(substr($0,i,1)>="\xS_INDEX" && substr($0,i,1)<="\xE_INDEX"){printf substr($0,i,1);f=1;} if(f)printf "\n"; f=0}' filename
这里S_INDEX
和E_INDEX
是 .ascii 中的起始和结束索引hex
。
对于输入:
1243
135
dgfsdaa
125
sdg124
sdf34
仅选择数字:S_INDEX = 30 和 E_INDEX = 39
输出:
1243
135
125
124
34