더 큰 파일을 정렬하면 분할 오류가 발생합니다.

더 큰 파일을 정렬하면 분할 오류가 발생합니다.
mkdir tmp
sort -u *.txt -T tmp/ -o output.txt

수십 기가바이트의 파일만 정렬하면 됩니다.

문제는 몇 분 후에 정렬이 분할된다는 것입니다.

운영 체제는 최신 Scientific Linux 6.6입니다.

질문:파일을 "정렬 -u"하는 방법은 무엇입니까? Sort는 더 큰 파일을 처리할 수 없나요? .. 세그폴트가 발생했을 때 RAM이 절반도 채 안 찼습니다.. 코어 하나만 100%였습니다.

답변1

과거에는 너무 큰 파일을 정렬해야 했습니다 sort. 제 생각에는 이것이 귀하의 문제이기도 하지만 더 많은 정보를 제공해 주시면 귀하의 문제를 더 잘 진단할 수 있을 것입니다.

grep내 문제에 대한 해결책은 전처리기를 사용하여 파일을 분할하는 것입니다. 데이터를 보고 덩어리가 어디에 있는지 확인하세요. 영숫자 공간에 잘 분산되어 있다고 가정하지만 나중에 클러스터를 처리하는 방법에 대해 논의하겠습니다.

for char1 in other {0..9} {a..z}; do
  out="/tmp/sort.$char1"
  echo "Extracting lines starting with '$char1'"
  if [ "$char1" = "other" ]; then char1='[^a-z0-9]'; fi
  grep -i "^$char1" *.txt > "$out"
  sort -u "$out" >> output.txt || break
done

(이것은 bashism을 사용합니다. 이를 방지하려면 37자 각각에 명시적으로 이름을 지정하십시오. 예를 들어 for char1 in other 0 1 2 3 4 5 6 7 8 9 0 a b c d e f ...)

덩어리:이러한 루프 호출 중 일부는 sort데이터가 너무 많아서 세그폴트가 발생할 수 있습니다. 반복을 수정하여 여러 부분으로 나누세요. 이는 grep에서 플래그를 제거하고 각 대문자를 불러오는 것만큼 간단할 수도 있고 -i(로 변경하는 것을 잊지 마세요 other) [^a-zA-Z0-9]데이터를 더 깊이 파헤쳐야 할 수도 있습니다. 이것이 패키지 목록이라면 "lib"로 시작하는 줄이 너무 많아서 반복이 /tmp/sort.l실패할 수 있습니다. || break이 루프의 일부는 이 시점에서 처리를 중지하므로 문제를 수정하고 중단한 부분부터 계속할 수 있습니다. "lib" 예제에 이어 다음과 같이 계속할 수 있습니다.

for char1 in 'l[a-h]' 'lia' lib{a..z} lib{0..9} 'li[c-z]' 'l[j-z]' {m..z}; do
  ...

그러면 l목록이 lib* 부분 앞과 뒤의 여러 부분으로 분할됩니다. 조금 보기 흉하지만 작동해야 합니다. 저장하려면 필요한 순서를 적어두세요.

답변2

또 다른 가능성은 각 파일을 개별적으로 정렬한 다음 병합하는 것입니다.

for f in *txt; do
    sort -u "$f" -T tmp/ > "$f".sorted
done
sort -mu *sorted

-m옵션은 sort정렬된 파일을 정렬하는 대신 병합합니다. 이로 인해 메모리 사용량이 훨씬 줄어들고 세그폴트를 방지할 수 있습니다.

답변3

다양한 답변 결합: 파일을 여러 조각으로 정렬하려면 분할을 사용해 보세요.

LARGETMP=/var/tmp
mkdir ${LARGETMP}
N_LINES=100000 # Adjust when to still too large or too small
split --lines=${N_LINES} bigfile splitted_
for small in splitted*; do
   sort -u -T ${LARGETMP} ${small} > sorted_${small}
   rm ${small}
done
echo "Done with sorting the splitted files, now concate the stuff"
sort -um -T ${LARGETMP} sorted_* > bigfile.sorted

편집: @ua2b가 언급했듯이 크기별로 분할하면 대부분 행 중간에서 분할됩니다.
(파일에 개행 문자가 없으면 정렬이라는 전체 아이디어가 약간 이상해집니다.)

답변4

OpenBSD에서 방법을 찾았습니다.

http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/sort.1?query=sort&sec=1

 -H
    Use a merge sort instead of a radix sort. This option should be used for files larger than 60MB.

하지만 이는 너무 많은 공간을 차지하기 때문에 완전히 좋은 해결책은 아닙니다. x>100 GByte로는 충분하지 않습니다.

관련 정보