나는 Originallist(dowork.sh Originallist)를 검토하고 있으며 clean1에서 수행되는 작업을 알려드립니다. clean1은 Originallist와 다르게 정렬됩니다. dowork.sh에서 처리할 남은 콘텐츠 목록을 생성해야 합니다. 기본적으로는 목록 청소R - 목록 청소1 = 목록 청소2입니다. 이것은 부정적인 작업입니다. 이 작업을 수행하려면 다음 grep 옵션을 사용할 수 있다는 것을 알았습니다.
- F는 정규식 대신 전체 줄 일치를 의미합니다. (우리는 grep이 파일 이름 문자에 대해 당황하고 정규식이라고 생각하는 것을 원하지 않습니다.)
- v는 제외(예: 빼기 기호 연산)를 의미합니다.
- f는 주어진 단일 표현식("파일에서 패턴 가져오기") 대신 clean1 파일에서 표현식을 찾습니다.
# wc -l cleaned*
9157094 cleaned1
14283591 cleanedR
# du -sh cleaned*
1.3G cleaned1
2.0G cleanedR
# grep -Fvf cleaned1 originallist > cleaned2
5분 동안 실행되고 42G 이하의 메모리를 소비하지만 이는 많은 양이며 실패하고 종료됩니다. clean2의 길이는 0바이트입니다.
끝에 있는 clean2는 14283591 - 9157094 = 5126497 줄 길이여야 합니다.
이것은 이와 같은 작업을 수행하는 올바른 구문이지만(나는 10줄 긴 cleanR과 3줄 긴 clean1로 테스트했습니다. 결과 clean2는 7줄 길이였습니다), 많은 메모리를 소비합니다. 너무 많은 메모리를 소비하지 않고 grep을 수행할 수 있는 방법이 있습니까? 시간이 좀 걸릴 것이라는 건 알지만 동의합니다.
나는 /tmp(내 경우에는 ram)를 사용하지 않고 다른 디렉토리를 사용할 수 있게 해주는 -T 옵션과 같은 것을 찾고 있습니다.
sort -h
-T, --temporary-directory=DIR use DIR for temporaries, not $TMPDIR or /tmp;
multiple options specify multiple directories
답변1
sort 명령은 상대적으로 일반적인 사용 사례인 대규모 데이터 세트 처리를 위한 특정 지원 기능을 제공합니다. 거대한 grep 패턴은 극히 드문 사용 사례이므로 개발자가 이에 많은 노력을 기울일 것이라고 기대할 수 없습니다.
줄의 순서가 중요하지 않은 경우 파일 길이에 관계없이 한 번에 몇 줄 이상 메모리에 저장하지 않고도 두 파일을 정렬한 다음 비교할 수 있습니다. 정렬을 통해 메모리가 부족한 파일을 처리할 수 있으므로 이는 효율적입니다.
sort originallist >originallist.sorted
sort cleaned1 | comm -23 originallist.sorted - >cleaned2.sorted
OriginalList의 원래 순서가 중요한 경우 행 번호를 추가할 수 있습니다.
nl -w 22 originallist >originallist.numbered
# then generate cleaned1 from the numbered list
originallist.numbered
정렬되었으므로 이를 실행하여 공통 행을 검색할 수 있습니다 comm
.
순서가 중요하고 행 번호를 매기기에는 너무 늦었다면 청크로 나누고 cleaned1
각 청크에 대해 단일 패스를 만들어 볼 수 있습니다. originallist
최근 GNU 분할:
cp originalfile cleaned2.in
split -l 1000000 --filter='grep -Fxv -f - cleaned2.in >cleaned2.out; mv cleaned2.out cleaned2.in' cleaned1
mv cleaned2.in cleaned2
( F
"전체 줄 일치"가 아니라 부분 문자열 일치를 수행합니다. 전체 줄 문자열 일치를 위해서는 -x
.)