Estrarre la sezione centrale delle righe di un file di testo?


17

Sto scrivendo uno script PHP per analizzare un file di testo di grandi dimensioni per eseguire inserimenti di database da esso. Tuttavia sul mio host, il file è troppo grande e ho raggiunto il limite di memoria per PHP.

Il file ha circa 16.000 righe; Voglio dividerlo in quattro file separati (all'inizio) per vedere se riesco a caricarli.

La prima parte che posso ottenere head -4000 file.txt. Le sezioni centrali sono leggermente più complicate: stavo pensando tailall'output delle tubazioni in head( tail -4001 file.txt | head -4000 > section2.txt), ma c'è un altro / modo migliore?

In realtà la mia logica è incasinata - per la sezione due, avrei bisogno di qualcosa del genere tail -12001 file.txt | head - 4000, quindi abbassare l' tailargomento per le sezioni successive. Mi sto già confondendo! : P

Risposte:


27

Se vuoi non essere incasinato ma farlo ancora usando taile head, c'è un modo utile di invocare tailusando un conteggio di riga dall'inizio, non la fine:

tail -n +4001 yourfile | head -4000

... Ma uno strumento migliore, automatico creato solo per dividere i file si chiama ... split! Fa anche parte dei coreutils GNU, quindi qualsiasi normale sistema Linux dovrebbe averlo. Ecco come puoi usarlo:

split -l 4000 yourInputFile thePrefixForOutputFiles

(Vedi in man splitcaso di dubbio.)


19

Combinando testa e coda come hai fatto funzionerà, ma per questo avrei usato sed

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

Ciò consente di risolvere il problema con una funzione di shell rapida

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

Ora hai your_file.1-4000 e yuor_file.4001-8000 e così via.

Nota: richiede bash


3
Mi piace il modo sed.
Fanchyna,

Questo non funziona per me perché sed non esce. Stampa le righe che voglio stdout, ma devo ctrl-c out e, di conseguenza, non posso reindirizzarlo su un file. Qualche suggerimento per renderlo utilizzabile?
Brent212,

Capito! "sed -n '<start_line>, <end_line> w <output_file>' <input_file>" funziona per me.
Brent212,

@ Brent212 Un'altra opzione da notare è che è anche possibile reindirizzarlo in meno o reindirizzare l'output su un file.
Kyle il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.