Extraire la section centrale des lignes d'un fichier texte?


17

J'écris un script PHP pour analyser un gros fichier texte pour en faire des insertions de base de données. Cependant sur mon hôte, le fichier est trop volumineux et j'ai atteint la limite de mémoire pour PHP.

Le fichier contient environ 16 000 lignes; Je veux le diviser en quatre fichiers distincts (au début) pour voir si je peux les charger.

La première partie que je peux obtenir head -4000 file.txt. Les sections centrales sont légèrement plus délicates - je pensais à canaliser la tailsortie dans head( tail -4001 file.txt | head -4000 > section2.txt), mais y a-t-il une autre / meilleure façon?

En fait, ma logique est foirée - pour la section deux, j'aurais besoin de quelque chose comme ça tail -12001 file.txt | head - 4000, puis abaisser l' tailargument pour les sections suivantes. Je m'embrouille déjà! : P

Réponses:


27

Si vous ne voulez pas vous tromper mais que vous le faites toujours en utilisant tailet head, il existe un moyen utile d'invoquer tailun décompte de lignes depuis le début, pas la fin:

tail -n +4001 yourfile | head -4000

... Mais un meilleur outil automatique conçu uniquement pour fractionner des fichiers s'appelle ... split! Il fait également partie de coreutils GNU, donc tout système Linux normal devrait l'avoir. Voici comment vous pouvez l'utiliser:

split -l 4000 yourInputFile thePrefixForOutputFiles

(Voir en man splitcas de doute.)


19

La combinaison de la tête et de la queue comme vous le ferez fonctionnera, mais pour cela j'utiliserais sed

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

Cela vous permet de résoudre votre problème avec une fonction shell rapide

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

Vous avez maintenant votre_fichier.1-4000 et yuor_file.4001-8000 et ainsi de suite.

Remarque: nécessite bash


3
J'aime la façon sed.
fanchyna

Cela ne fonctionne pas pour moi car sed ne sort pas. Il imprime les lignes que je veux stdout, mais je dois ctrl-c sortir, et par conséquent, je ne peux pas le rediriger vers un fichier. Une suggestion pour le rendre utilisable?
Brent212

Deviner! "sed -n '<start_line>, <end_line> w <output_file>' <input_file>" fonctionne pour moi.
Brent212

@ Brent212 Une autre option à noter est que vous pouvez également le rediriger vers moins ou rediriger la sortie vers un fichier.
Kyle s
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.