아래와 같이 4개의 열이 있는 CSV 파일이 있습니다.
aa,bb,cc,dd
ee,bb,cc,dd
ff,bb,cc,dd
xx,11,22,33
yy,11,22,33
나는 그것을 다음과 같이 바꾸고 싶습니다 :
aa,ee,ff,bb,cc,dd
xx,yy,11,22,33
기본적으로 마지막 3개의 동일한 열이 있는 행을 찾아 첫 번째 필드를 병합합니다.
Bash나 Python에서 이 작업을 수행하는 방법을 아는 사람이 있나요?
답변1
다음은 프로그램입니다 awk
:
#!/bin/awk -f
BEGIN {OFS = FS = ","}
{
gsub(/ +$/, "", $4)
field = $2","$3","$4
if (field in a)
a[field] = a[field]","$1
else
a[field] = $1
}
END { for (i in a) print a[i], i}
추가 Python 프로그램이 있습니다:
from collections import OrderedDict
records = OrderedDict()
for line in open('file1'):
field, key = line.strip().split(',', 1)
records.setdefault(key, []).append(field)
for key, fields in records.items():
print(','.join(fields + [key]))
결과:
aa,ee,ff,bb,cc,dd
xx,yy,11,22,33
답변2
진주
해시는 %h
데이터를 보유하고 배열은 @h
해시 요소가 발견되는 순서를 관리합니다. OTW, 해시 키는 무작위 순서로 선택됩니다.
perl -F, -lane '
BEGIN{ $"=$,=","; }
push @{$h{"@F[-3..-1]"}}, $F[0];
$h[-1+keys %h] = "@F[-3..-1]";
END{ print @{$h{$_}}, $_ for @h; }
' yourcsvfile
옆
sed -e '
:loop
$!N
s/^\(.*\)\(\(,[^,]*\)\{3\}\)\n\([^,]*\)\2$/\1,\4\2/
tloop
P;D
' yourcsvfile
불다
sed \$G yourcsvfile | # we add a dummy line to signal last record has been processed
while IFS=, read -r -a A; do
var=${A[@]: -3:3}
var=${var// /,}
case $var in
"$prev" ) x=${x-}${x:+,}${A[0]} ;;
* ) case $prev in ?* ) echo "$x,$prev" ;; esac; prev=$var; x=${A[0]} ;;
esac
done