다음 예를 데이터로 사용하여 각 개별 필드에서 중복 항목을 제거하는 방법.
0x,9.4,,,#0,#UNIX#unix,#cli#L#فا#0#فا#0#L#SE#Cli#SE,#فارسی#فارسی#۱#1#١#1,bsh,#V & v
예상 출력(모든 중복 항목 제거, 대소문자 구분 안 함, 유니코드 "페르시아어 #۱
/아랍어 #١
" 차이, 항목 순서 및 유지해야 하는 항목(대소문자 무시)은 여기에서 중요하지 않음):
0x,9.4,,,#0,#unix,#cli#L#فا#0#SE,#فارسی#١#۱#1,bsh,#V & v
패턴은 이 형식을 사용하며 #x
하나 x
이상의 문자 길이를 나타냅니다.
답변1
사용하다진주쉘의 명령줄(단 몇 줄)에 적절한데이터 세트파서:
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
데비안 및 파생 제품용
답변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