extrai a seção intermediária de linhas de um arquivo de texto?

13

Eu estou escrevendo um script php para analisar um arquivo de texto grande para inserções de banco de dados a partir dele. No entanto, no meu host, o arquivo é muito grande e eu atingi o limite de memória para php.

O arquivo tem cerca de 16.000 linhas; Eu quero dividi-lo em quatro arquivos separados (primeiro) para ver se consigo carregá-los.

A primeira parte que posso obter com head -4000 file.txt . As seções do meio são um pouco mais complicadas - eu estava pensando em direcionar tail output para head ( tail -4001 file.txt|head -4000 > section2.txt ), mas existe outra maneira melhor?

Editar na verdade, minha lógica está desarrumada - para a segunda seção, eu precisaria de algo como tail -12001 file.txt|head - 4000 e, em seguida, diminuir o argumento tail para as próximas seções. Estou me misturando já! : P

    
por user394 14.10.2011 / 18:56

2 respostas

21

Se você não quiser ficar confuso, mas continuar usando tail e head , há uma maneira útil de invocar tail usando uma contagem de linhas desde o início, não o final:

tail -n +4001 yourfile | head -4000

... Mas uma ferramenta melhor e automática feita apenas para dividir arquivos é chamada ... split ! É também uma parte do GNU coreutils, então qualquer sistema normal de Linux deveria tê-lo. Veja como você pode usá-lo:

split -l 4000 yourInputFile thePrefixForOutputFiles

(Veja man split em caso de dúvida.)

    
por 14.10.2011 / 19:13
14

Combinar cabeça e cauda como você funciona, mas para isso eu usaria sed

sed -n '1,4000p' input_file # print lines 1-4000 of input_file

Isso permite que você resolva seu problema com uma função de shell rápida

chunk_it(){
    step=4
    start=1
    end=$step
    for n in {1..4} ; do
        sed -n "${start},${end}p" "$1" > "$1".$start-$end
        let start+=$step
        let end+=$step
    done
}

chunk_it your_file

Agora você tem your_file.1-4000 e yuor_file.4001-8000 e assim por diante.

Nota: requer bash

    
por 14.10.2011 / 19:16