main.txt
아래와 같은 데이터 파일이 있습니다.
20130826,aaaaaaaaaaaaaa,bbbbbbb
20130826,sdfasdfasdfas,sdfasdfasd
20130826,dfasdfas,asdf2323
...
20130827,sfasdfasdfasd,sdfasdfwea
나는 main.csv
날짜별로 더 작은 파일로 분할하기 위해 다음 awk 조각을 사용하고 있습니다.
cat test01 | stdbuf -oL -eL awk -F',' '{print $2","$3 >> "data"$1".csv"; fflush()}'
분할 파일 data20130826.csv의 마지막 줄이 불완전한 것을 발견했습니다.
...
20130826,dfasdfas,asdf2323
2013082
실제로 날짜 20130826의 마지막 몇 행(10개 정도)이 누락되었으며 data20130827.csv에 없습니다. 버퍼링을 끄기 위해 위의 줄을 따라해 보았지만 도움이 되지 않는 것 같습니다. 메인 파일은 괜찮을 것 같아요. 무엇이 잘못되었나요? 저는 GNU Awk 4.0.1을 사용하고 있습니다.
답변1
내 원래 게시물을 명확히 하기 위해: 나는 Orion의 의견에 동의하며 이것이 이상한 버그라고 생각합니다. 나는 fflush에도 신경 쓰지 않을 것입니다. 나는 이것이 데이터로 인한 이상한 문제라고 생각합니다. 특히, 파일의 각 날짜마다 하나씩 열려 있는 파일 설명자가 너무 많은 것 같습니다. 또는 같은 이유로 버퍼 제한에 도달했을 수도 있습니다. 열려 있는 파일이 너무 많습니다. fflush는 열린 파일을 닫지 않고 단지 버퍼를 플러시합니다.
그렇다면 입력 파일에는 몇 개의 다른 날짜가 있습니까? 다음은 열려 있는 파일 수입니다.
cut -d"," -f1 test01 | sort | uniq | wc -l
- 파일이 수백 개라면 언제든지 파일 닫기에 대한 두 번째 제안을 참조하세요.
두 가지 제안:
1. 데이터가 숨겨진 문자(예: 백스페이스) 없이 일반 텍스트이고 일반 UNIX 줄 끝도 포함하고 있습니까? "20130826"이라는 접두사가 붙은 줄을 찾아 정상적으로 보이고 실제로는 모두 별도의 줄인지 확인할 수 있습니까?
cat test01 | grep "^20130826"
- and also run
cat test01 | grep -c "^20130826"
- grep 줄 번호가 출력 파일의 내용과 일치하는지(또는 일치하지 않는지) 확인하세요.
2. 입력 데이터가 날짜 순서로 정렬되어 있으면 파일을 작성하는 동안 파일을 닫아 볼 수 있습니다. 원래 게시물 이후 이것을 테스트했는데 잘 작동했습니다.
cat test01 | awk -F"," '{prevfile=ofile; ofile=sprintf("data%s.csv",$1);
if (NR > 1 && ofile != prevfile) close(prevfile); print $2","$3 >> ofile}'
파일이 날짜별로 정렬되지 않은 경우에도 이 코드는 작동하지만 파일을 더 자주 열고 닫게 됩니다. 이 경우 명령 시작 부분에서 "cat test01"을 "sort test01"로 변경하면 됩니다.
awk를 사용할 때 항상 명시적으로 파일을 닫을 필요는 없지만, 내 경험상 이러한 파일을 닫지 않고 많이 작성하면 awk가 충돌할 수 있습니다. 이는 제 생각에 여전히 적용될 수 있습니다. 파일 설명자를 엽니다.
또한 이러한 파일에 추가할 때 명령을 실행하기 전에 파일에 데이터가 포함되어 있지 않은지 확인하세요. 일이 잘 안 풀리면 잊어버리기 쉽죠...
답변2
노력하다:
$ cat test01 |
stdbuf -oL -eL awk -F',' '{print $2","$3 >> "data"$1".csv"; fflush("")}'
에 gawk 4.0.1
전화해플러시()인수 없이 표준 출력을 플러시하면 됩니다. 열려 있는 모든 출력 파일과 파이프를 플러시 하려면 fflush()
빈 문자열을 사용하여 호출 해야 합니다 .""
awk
이후 사용 시 gawk 4.0.2
인수가 없거나 인수가 fflush()
빈 문자열 인 ""
경우 awk
열려 있는 모든 출력 파일 및 파이프의 버퍼를 플러시합니다.