如何使用以下示例作为数据删除每个单独字段中的重复条目。
0x,9.4,,,#0,#UNIX#unix,#cli#L#فا#0#فا#0#L#SE#Cli#SE,#فارسی#فارسی#۱#1#١#1,bsh,#V & v
预期输出(删除所有重复的、不区分大小写、Unicode“波斯语#۱
/阿拉伯语#١
”的差异、条目顺序以及应保留哪个条目(忽略大小写)在这里并不重要):
0x,9.4,,,#0,#unix,#cli#L#فا#0#SE,#فارسی#١#۱#1,bsh,#V & v
该模式采用这种格式#x
,x
表示一个或多个字符长度的任何内容。
答案1
用一个珀尔shell 中的命令行(只需几行),并带有适当的数据集解析器:
perl -CS -Mopen=":std,IN,OUT,IO,:encoding(utf8)" -MText::CSV -lne '
BEGIN{
our $csv = Text::CSV->new({ sep_char => "," });
sub uniq { my %seen; grep !$seen{lc $_}++, @_; }
};
$csv->parse($_) or die "parse error";
print join ",", map { join "#", uniq split /#/ } $csv->fields();
' file.csv
输出 :
0x,9.4,,,#0,#UNIX,#cli#L#فا#0#SE,#فارسی#۱#1#١,bsh,#V & v
笔记 :
- 需要安装
Text::CSV
perl 模块:sudo apt-get install libtext-csv-perl
对于 debian 和衍生版本
答案2
完全的Python
解决方案:
uniq_arabic_csv.py
脚本:
#!/bin/python
import sys, re
csv_data = sys.stdin.read().strip()
result = []
for item in csv_data.split(','):
matches = list(re.finditer(r'#[^#]+', item, re.U | re.I))
if not matches or len(matches) == 1:
result.append(item)
else:
s, res = set(), []
for m in matches:
m = m.group()
if m.lower() not in s: res.append(m)
s.add(m.lower())
result.append(''.join(res))
result = ','.join(result)
print(result)
用法:
s="0x,9.4,,,#0,#UNIX#unix,#cli#L#فا#0#فا#0#L#SE#Cli#SE,#فارسی#فارسی#۱#1#۱#1,bsh,#V & v"
python uniq_arabic_csv.py <<<"$s"
输出:
0x,9.4,,,#0,#UNIX,#cli#L#فا#0#SE,#فارسی#۱#1,bsh,#V & v
答案3
我awk
也在下面编写了简单的解决方案:
awk -F, '{ i=0; comma=""; while (++i<=NF) {
if ( split(tolower($i), arr, /#/)>1 ){ for(v in arr) !unq[arr[v]]++;printf comma;
for (x in unq) {printf (x!="")?hash""x:""; hash="#"; delete unq[x]}}
else {printf comma""$i; comma=","}}; print ""
}' infile.csv