tags:

views:

177

answers:

1

I have a giant text file (about 1,5 gigabyte) with xml data in it. All text in the file is on a single line, and attempting to open it in any text editor (even the ones mentioned in this thread: http://stackoverflow.com/questions/159521/text-editor-to-open-big-giant-huge-large-text-files ) either fails horribly or is totally unusable due to the text editor hanging when attempting to scroll.

I was hoping to introduce newlines into the file by using the following sed command

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

Sadly, this caused sed to give me a segmentation fault. From what I understand, sed reads the file line-by-line which would in this case mean that it attempts to read the entire 1,5 gig file in one line which would most certainly explain the segfault. However, the problem remains.

How do I introduce newlines after each > in the xml file? Do I have to resort to writing a small program to do this for me by reading the file character-by-character?

+2  A: 

some sed has a limit on that. GNU sed has no limit as long as it can `malloc()' more (virtual) memory, you can feed or construct lines as long as you like. (from the doc)

I would suggest, if possible, to change how you create that xml file. ( Why is it all in one line in the first place ? ). Otherwise, you could read it one character by character. eg using the shell

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

or

while read -n 1000 str ; do
 echo "${str//>/>
}"
done < file
ghostdog74
Good one, but can be optimized by: `while read -n 1000 str ; do echo -n "$str" | sed 's/>/>\n/g' ; done < file`
Chen Levy
Oh believe me, I've asked myself several times why it's all in one line in the first place (often followed by some very creative cursing) :) Sadly it's not something I can do anything about. The reading one character at a time idea seems to work pretty well though. I'd hoped to not have to do that, but it works. Thanks!
wasatz
@Chen, i would cut the use of `sed` and just use internal shell substituion
ghostdog74
@ghostdog74, I thought your suggestion is cool, but I timed `while read -n 1000 str ; do echo -ne "${str//>/>\n}" ; done < file` and it turned out to be significantly slower. Even slower then the one char at a time code above.
Chen Levy
i believe not. calling external command is definitely slower than calling in built.
ghostdog74
Your theory is sound, but I *did* test it. My guess is that the `sed` implementation is significantly more efficient then of the bash parameter expansion.
Chen Levy
if you are talking about just using sed, then yes, BUT i am talking about using the `while loop + sed` vs `while loop + internals`. In that case, using `while loop + sed` is definitely slower.
ghostdog74