2010-03-18 4 views
4

J'ai un fichier texte géant (environ 1,5 gigaoctet) contenant des données xml. Tout le texte dans le fichier est sur une seule ligne, et tenter de l'ouvrir dans n'importe quel éditeur de texte (même ceux mentionnés dans ce fil: Text editor to open big (giant, huge, large) text files) échoue horriblement ou est totalement inutilisable en raison de l'éditeur de texte suspendu en essayant de faire défiler.Utilisation de sed pour introduire une nouvelle ligne après chaque> dans un fichier texte d'une ligne d'un gigaoctet +1 gigaoctet

J'espérais d'introduire les nouvelles lignes dans le fichier en utilisant la commande sed suivante

sed 's/>/>\n/g' data.xml > data_with_newlines.xml 

Malheureusement, cela a causé sed de me donner une erreur de segmentation. D'après ce que je comprends, sed lit le fichier ligne par ligne ce qui dans ce cas signifierait qu'il essaye de lire le fichier entier de 1,5 gig sur une ligne ce qui expliquerait certainement le segfault. Cependant, le problème demeure. Comment puis-je introduire des nouvelles lignes après chaque> dans le fichier XML? Dois-je recourir à un petit programme pour faire cela en lisant le fichier caractère par caractère?

+2

Vous pourriez avoir plus de chance avec tr. –

+0

tr ressemble à un outil utile, je ne savais pas à ce sujet avant, merci de m'en avoir parlé! – wasatz

+0

+1; question intéressante – sixtyfootersdude

Répondre

4

certains sed a une limite à cela. GNU sed n'a pas de limite tant qu'il peut plus de mémoire (virtuelle) `malloc() ', vous pouvez nourrir ou construire des lignes aussi longtemps que vous le souhaitez. (de la doc)

Je suggérerais, si possible, de changer la façon dont vous créez ce fichier xml. (Pourquoi est-ce tout dans une ligne en premier lieu?). Sinon, vous pourriez le lire un caractère par caractère. par exemple en utilisant le shell

while read -n 1 ch 
do 
    case "$ch" in 
    ">") printf "%s\n" "$ch";; 
    *) printf "%s" $ch;; 
    esac 
done <"file" 

ou

while read -n 1000 str ; do 
echo "${str//>/> 
}" 
done < file 
+1

Bon, mais peut être optimisé par: 'while read -n 1000 str; fais echo -n "$ str" | sed 's /> /> \ n/g'; done

+0

Oh croyez-moi, je me suis demandé à plusieurs reprises pourquoi tout est dans une ligne en premier lieu (souvent suivi d'une malédiction très créative) :) Malheureusement, ce n'est pas quelque chose que je peux faire quelque chose. La lecture d'un personnage à la fois semble fonctionner plutôt bien. J'espérais ne pas avoir à faire ça, mais ça fonctionne. Merci! – wasatz

+0

@Chen, je voudrais couper l'utilisation de 'sed' et juste utiliser la substitution de la coque interne – ghostdog74

Questions connexes