두 개의 열이 있는 test1.csv 파일이 있습니다.
group,email
[email protected],[email protected]
[email protected],[email protected]
[email protected],[email protected]
[email protected],[email protected]
[email protected],[email protected]
[email protected],[email protected]
[email protected],[email protected]
[email protected],[email protected]
[email protected],[email protected]
내 목표는 첫 번째 열의 값을 기반으로 별도의 텍스트 파일을 만드는 것입니다.
예를 들어:
첫 번째 파일 이름은[이메일 보호됨]그리고 포함
[email protected]
[email protected]
[email protected]
[email protected]
첫 번째 파일 이름은[이메일 보호됨]그리고 포함
[email protected]
[email protected]
등.
이 awk 명령이 있습니다
awk -F"," 'NR==1{header=$0}NR>2&&!a[$1]++{print header > (""$1"")}NR>2{print > (""$1"")}' test1.csv
그러나 파일 이름이 올바르게 지정되었음에도 불구하고 결과는 내가 정말로 원하는 것이 아닙니다.
group,email
[email protected],[email protected]
[email protected],[email protected]
[email protected],[email protected]
또한 .csv 파일이 너무 커질 때마다 "Awk: 열린 파일이 너무 많습니다"라는 메시지가 표시됩니다.
도움을 주시면 감사하겠습니다. 또한 sed나 grep과 같은 다른 언어도 살펴보세요.
답변1
이것이 당신에게 필요한 것입니다:
awk -F ',' 'NR<2{next} p1!=$1&&p1{close(p1)} {p1=$1;print $2>p1}' file
NR<2{next}
: 제목을 건너뜁니다.p1!=$1&&p1{close(p1)}
:p1
이전 줄의 첫 번째 필드( )가 현재 줄의 첫 번째 필드와 다른 경우 "너무 많은 열린 파일"이 발생하지 않도록 이전 출력 파일이 닫힙니다(아직 열린 파일이 없는 한). 및 열기p1
). 설정되지 않음).{p1=$1;print $2>p1}
: 첫 번째 필드를p1
변수에 넣고 두 번째 필드를 첫 번째 필드 이름의 파일에 인쇄합니다.
file
위의 awk에서는 제공된 예에 표시된 것처럼 첫 번째 필드가 동일한 행이 에서 함께 그룹화되어 있다고 가정합니다 . 그렇지 않은 경우 간단한 해결책은 awk에 정렬된 입력을 제공하고 헤더를 명시적으로 건너뛰는 것입니다(헤더가 더 이상 첫 번째 줄에 없기 때문에).
sort file | awk -F ',' '/^group,email$/{next} p1!=$1&&p1{close(p1)} {p1=$1;print $2>p1}'
답변2
awk
제공된 파일 이름으로 직접 리디렉션 할 수 있습니다 (도메인 이름은 공백에 안전해야 함).$2
$1
awk -F, 'NR>1{print $2 > $1}' file
헤더를 건너뛰고 파일을 열어 둡니다. 헤더를 ++h[$1]==1
쓸 새 파일 인지 테스트한 다음 다음을 사용하여 추가하여 이 문제를 해결할 수 있습니다.>
>>
$2
close($1)
awk -F, '
NR==1{header=$0}
NR>1{
if(++h[$1]==1)print header > $1;
print $2 >> $1; close ($1)
}' file
중복을 피하려면 ++f[$0]==1
첨부하기 전에 테스트하십시오.
awk -F, '
NR==1{header=$0}
NR>1&&++f[$0]==1{
if(++h[$1]==1)print header > $1;
print $2 >> $1; close ($1)
}' file
head *.com
==> [email protected] <==
group,email
[email protected]
[email protected]
[email protected]
[email protected]
==> [email protected] <==
group,email
[email protected]
[email protected]
==> [email protected] <==
group,email
[email protected]
[email protected]
[email protected]
파일이 완전히 또는 부분적으로 정렬된 경우 다음과 같이 각 줄을 맹목적으로 열고 닫는 것을 방지할 수 있습니다.
awk -F, '
NR==1{header=$0}
NR>1&&++f[$0]==1{
if ($1 != old) close(old);
if(++h[$1]==1)print header > $1;
print $2 >> $1; old=$1
}' file
이는 데이터 파일을 사용하기 때문에 $2 >>
두 번째 블록이 있어도 상관 없으며 $1
새 블록에 의해 삭제되지 않습니다.>
답변3
밀러 사용(https://github.com/johnkerl/miller) 간단히 말해서
mlr --csv put -q 'tee > $group, $*' ./input.csv
mlr -I --c2n cut -f email ./group*@*
이건 이상한 일이 아니지만 당신에게 효과가 있을 거라고 생각했어요
답변4
$ awk '{print (NR>1),$0}' file | sort -k1,1n -k2 | cut -d' ' -f2- |
awk -F, '
NR==1 { hdr=$0; next }
$1 != out { close(out); out=$1; print hdr > out }
{ print $2 " > " out }
'
위의 코드는 거의 모든 크기의 입력 파일에 대한 모든 awk에서 작동하며 입력 줄의 순서는 상관 없으며 빠릅니다.
테스트 완료 후 실제로 출력 파일을 생성 print $2 " > " out
하도록 변경되었습니다 .print $2 > out