를 사용하여 파일의 첫 번째 열 값을 기준으로 파일을 여러 파일로 분할하고 싶지만 zcat file2split.gz | awk '{print>$1}'
다음 오류가 발생합니다.
awk: cmd. line:1: (FILENAME=file2split FNR=1666) fatal: can't redirect to `CCTGGCAG_GATATAAC_HAP1' (Operation not permitted)
어떤 아이디어가 있나요? 감사해요!
zip 데이터 크기는 25Mb이며 여기에서 다운로드할 수 있습니다. https://drive.google.com/file/d/1Qjq-ibdiyemBfuqpoC2h0VDhw09PS0ao/view?usp=sharing
답변1
현재 출력 파일 이름이 변경될 때마다 이전 파일 이름을 닫으면 열린 파일 제한이 발생하는 것을 방지할 수 있습니다. 예를 들어
awk '{ out=$1;
if (out != lastfile) {
if (lastfile != "") { close(lastfile) };
lastfile = out
};
print > out'
파일을 닫았다가 다시 여는 것보다 훨씬 낫습니다.모든쓰다. 마지막으로 작성된 이후 이름이 변경된 경우에만 파일을 닫습니다. 파일이 필드 1로 정렬되면 파일을 다시 열 필요가 없습니다. "대부분 정렬"된 경우 파일을 다시 열 필요가 거의 없습니다.
참고: 동일한 파일 이름이 여러 번 나타날 수 있는 경우인접하지 않음print >> out
줄이 있으면 대신 출력을 추가해야 합니다 print > out
. 그렇지 않으면 파일이다시 열다쓰기의 경우 쓰기 전에 완전히 덮어쓰게 됩니다(즉, 0 크기로 잘립니다).
(그런데 이것이 쓰기 작업을 할 때마다 파일이 자동으로 닫히지 않는 이유 중 하나입니다 awk
. 물론, 또 다른 주된 이유는 이렇게 하지 않으면 같은 파일을 쓸 때마다 닫았다가 다시 열면 많은 시간이 소요될 것이기 때문입니다. 더 느리게.
awk 스크립트의 특정 실행에서 처음으로 파일을 덮어쓰고 동일한 실행에서 동일한 파일이 다시 표시되면 추가하려는 경우 이는 약간 더 복잡합니다. 예를 들어
awk '{ out=$1;
if (out != lastfile) {
if (lastfile != "") { close(lastfile) };
lastfile = out
};
if (seen[out]++) {
print >> out
} else {
print > out
}'
이 버전은 연관 배열을 사용하여 seen
이전에 특정 파일 이름을 본 적이 있는지 추적합니다. 그렇다면 추가해 주세요. 그렇지 않은 경우 덮어씁니다.
답변2
너무 많은 파일을 동시에 열어 두는 것이 실제로 현재 문제를 일으키는지는 의심스럽습니다. 하지만 참고로 원하는 작업을 수행하는 강력하고 효율적인 방법은 GNU sort for -s
및 awk를 사용하여 다음을 수행하는 것입니다.
zcat file2split.gz |
sort -s -k1,1 |
awk '
$1 != out {
close(out)
out = $1
}
{ print > out }
'
GNU 정렬이 없으면 다음 표준 Unix 도구의 모든 버전을 사용하여 동일한 작업을 수행할 수 있습니다.
zcat file2split.gz |
awk -v OFS='\t' '{print NR, $0}' |
sort -k2,2 -k1,1n |
cut -f2- |
awk '
$1 != out {
close(out)
out = $1
}
{ print > out }
'
awk가 출력 파일 생성을 시작하기 전에 입력을 정렬하는 위의 방법을 사용하면 awk는 한 번에 하나의 출력 파일만 열며 출력 파일을 여러 번 열 필요가 없습니다. 그냥 열고 쓰기만 하면 됩니다.모두라인을 연결한 후 닫고 다음 출력 파일로 이동합니다.