A classificação de arquivos maiores gera uma falha de segmentação

4
mkdir tmp
sort -u *.txt -T tmp/ -o output.txt

existem apenas alguns arquivos com 10 GB de tamanho que precisam ser classificados ...

O problema é que, após alguns minutos, a classificação fornece uma falha de segmentação.

O SO é um moderno Scientific Linux 6.6.

Pergunta: Como posso "classificar -u" os arquivos? A classificação não pode manipular arquivos maiores? .. A RAM não está cheia pela metade quando se trata de segfaults .. apenas um núcleo está em 100%

    
por somelooser28533 03.03.2015 / 21:41

5 respostas

3

No passado, eu tive que classificar arquivos grandes demais para sort . Presumo que este seja também o seu problema, embora, se fornecer mais informações, talvez possamos diagnosticar melhor o seu problema.

A solução para meu problema foi dividir o arquivo com grep como pré-processador. Dê uma olhada nos seus dados para ver onde os aglomerados estarão. Eu estou supondo que é decentemente espalhado sobre o espaço alfanumérico, mas vou discutir como lidar com grumos mais tarde.

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

(Isso usa um bashumano. Para evitá-lo, nomeie explicitamente cada um dos 37 caracteres, como for char1 in other 0 1 2 3 4 5 6 7 8 9 0 a b c d e f ... )

Clumps: É completamente possível que algumas dessas chamadas em sort em loop sejam segmentadas devido a ter muitos dados. Apenas revise essa iteração para ficar mais dividida em partes. Isso pode ser tão simples quanto remover o sinalizador -i do grep e chamar cada letra maiúscula (não se esqueça de alterar o other para [^a-zA-Z0-9] ), ou pode ser necessário escavar os dados. Se esta for uma lista de pacotes de software, você pode ter muitas linhas que começam com "lib" e, portanto, a iteração /tmp/sort.l falhará. A parte || break desse loop interromperá o processamento neste ponto para que você possa corrigi-lo e continuar de onde parou. Seguindo o exemplo "lib", você pode querer continuar com algo assim:

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

Isso divide a lista l em partes antes e depois da porção lib *. É um pouco feio, mas deve funcionar. Basta prestar atenção à ordem desejada para que você possa preservá-la.

    
por 08.03.2015 / 22:45
3

Outra possibilidade seria classificar cada um dos arquivos separadamente e depois mesclá-los:

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

A opção -m faz com que sort mescle arquivos já classificados em vez de tentar classificá-los. Isso deve resultar em um uso de memória muito menor e deve evitar o segfault.

    
por 11.03.2015 / 15:48
2

Combinando as diferentes respostas: Quando você quiser classificar o arquivo em partes, tente usar o split:

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

Editar: Como @ ua2b comentou, a divisão no tamanho geralmente será dividida no meio das linhas. (Quando o arquivo não tem feeds de linha, toda a idéia de classificação é um pouco estranha).

    
por 11.03.2015 / 22:22
1

A classificação precisará de um local de disco rígido para armazenar dados temporários. / tmp não é o melhor lugar. O comando sort armazena dados de trabalho em arquivos de disco temporários. Você pode usar o sinalizador -T para especificar um diretório temporário grande (em uma partição com muito espaço livre).

    
por 07.03.2015 / 23:06
0

Eu encontrei uma maneira no OpenBSD:

link

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

Mas esta não é uma solução totalmente OK, já que ocupa muito espaço ... x 100GB não é suficiente para isso ...

    
por 14.03.2015 / 13:31

Tags