다음과 같은 CSV 파일이 있습니다 file1.csv
.
something;AD;sss;Andorra;nothing;type_1;sss
something222;AD;sss222;Andorra;nothing222;type_2;aaa
thing;NL;thing3;Netherlands;thing;type_2;bb
etc;US;etc;United States;etc;type_2;nothing
국가별로 별도의 파일을 만들고 싶습니다. 나는 다음과 같이 grep을 만듭니다.
grep -e "\;AD\;.*\;Andorra\;" file1.csv > fileAD.csv
grep -e "\;NL\;.*\;Netherlands\;" file1.csv > fileNL.csv
grep -e "\;US\;.*\;United\sStates\;" file1.csv > fileUS.csv
이것은 효과가 있지만 전 세계의 모든 국가가 있으므로 각 국가에 대해 이 줄을 쓰고 싶지 않습니다. 다른 해결책이 있나요?
type_1
또한 및 이 포함된 열이 있습니다 type_2
. 이 점을 고려해야 합니다. 국가별 파일을 모두 만든 후에는 국가별로 새 파일을 만들어서 type_1
사용해야 합니다 type_2
.
예를 들어 안도라의 경우 다음 파일이 필요합니다.
fileAD.csv
:something;AD;sss;Andorra;nothing;type_1;sss something222;AD;sss222;Andorra;nothing222;type_2;aaa
fileADtype_1.csv
:something;AD;sss;Andorra;nothing;type_1;sss
fileADtype_2.csv
:something222;AD;sss222;Andorra;nothing222;type_2;aaa
약어가 있는 열만 찾는 것이 괜찮다고 생각하지만 보안상의 이유로 두 개의 열을 원합니다. 하나는 AD
전체 이름이고 다른 하나는 전체 이름입니다.Andorra
답변1
데이터가 다음과 같다고 가정합니다.단순한CSV 데이터, 즉 필드에 구분 기호나 줄 바꿈이 포함되어 있지 않습니다.
awk -F ';' '
{
print > "file" $2 ".csv"
print > "file" $2 $6 ".csv"
}' file1.csv
이렇게 하면 각 행이 두 번 인쇄됩니다. 한 번은 두 번째 필드 값으로만 지정된 파일에, 한 번은 두 번째와 여섯 번째 필드 값의 조합으로 지정된 파일에 인쇄됩니다. 질문의 텍스트에 따르면 각 출력 파일 이름에는 문자열 접두사가 붙고 file
접미사가 붙습니다..csv
파일 이름에 사용된 두 필드의 값은 검증되지 않습니다.
네 번째 필드에 국가 이름을 병합하려면:
awk -F ';' '
{
print > "file_" $2 "-" $4 ".csv"
print > "file_" $2 "-" $4 "_" $6 ".csv"
}' file1.csv
주어진 데이터에 대해 다음 파일이 생성됩니다.
file_AD-Andorra.csv
file_AD-Andorra_type_1.csv
file_AD-Andorra_type_2.csv
file_NL-Netherlands.csv
file_NL-Netherlands_type_2.csv
file_US-United States.csv
file_US-United States_type_2.csv
위의 코드는 GNU를 사용하는 시스템에서 잘 작동합니다 awk
. 다른 awk
구현에서는 동시에 쓰기 위해 너무 많은 파일을 열어 놓으면 문제가 발생할 수 있습니다. 이러한 awk
구현에서는 더 똑똑해야 하며 파일에 쓴 후에는 파일을 닫는 것을 기억해야 합니다. 파일이 닫혀지면 >>
다음에 데이터가 파일에 기록될 때 인쇄해야 합니다. 그렇지 않으면 파일이 잘립니다.
awk -F ';' '
function do_print(name) {
if (seen[name] == 1) print >>name # append to file
else print >name # first write, truncate file
close(name)
seen[name] = 1
}
{
do_print("file_" $2 "-" $4 ".csv")
do_print("file_" $2 "-" $4 "_" $6 ".csv")
}' file1.csv
awk
그러면 표현식을 사용할 수 없는 OpenBSD에서도 코드가 실행됩니다 print >
.
추가 (재미를 위해): awk
코드에서 일부 통계를 출력하도록 합니다.
awk -F ';' '
function do_print(name) {
if (seen[name] > 0) print >>name # append to file
else print >name # first write, truncate file
close(name)
seen[name]++
}
{
do_print("file_" $2 "-" $4 ".csv")
do_print("file_" $2 "-" $4 "_" $6 ".csv")
}
END {
for (name in seen)
printf "Wrote %d lines to \"%s\"\n", seen[name], name >"/dev/stderr"
}' file1.csv
처리가 끝나면 오류 스트림에 일부 통계가 기록됩니다. 주어진 데이터에 대해:
Wrote 1 lines to "file_NL-Netherlands.csv"
Wrote 1 lines to "file_US-United States_type_2.csv"
Wrote 1 lines to "file_AD-Andorra_type_1.csv"
Wrote 2 lines to "file_AD-Andorra.csv"
Wrote 1 lines to "file_NL-Netherlands_type_2.csv"
Wrote 1 lines to "file_US-United States.csv"
Wrote 1 lines to "file_AD-Andorra_type_2.csv"