Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I am having a hard time doing something quite simple. I have around 2000 .txt files which are composed of a single line of digits. I would like to fold the single line into one column with many rows, using the fold command and overwrite the original file with this new, folded version. My attempt:

#!/bin/bash
for i in *.txt ; do
  fold -w 1 $file > $file
done

Doesn't work. Help? Thanks.

share|improve this question
    
To avoid the need to directly handle and clean-up temporary files, see sponge from the moreutils package, at “In-place” editing of files, –  Peter.O Aug 17 '12 at 20:20
add comment

2 Answers

up vote 5 down vote accepted

There are two problems here. First, you are declaring the variable "i" but using "$file" which does not exist. Even if it did, the second problem is that bash reads "left to right". That means that it will first see ">$file", and will overwrite the file's contents. Therefore, if you were using the correct variables, you would have lost your data.

So, one error saved you from the other, you lucky, lucky fellow :)

Try something like:

for i in *.txt ; do fold -w 1 $i > sillytmpfile; mv sillytmpfile $i; done
share|improve this answer
    
In my defence I have killa flu. Will give it a go. Just out of curiosity. I have 18gb of txt files. Any way of doing it without a temp file? Thanks. –  Frank_Zafka Aug 17 '12 at 15:22
1  
@RSoul The tmpfile is created once for every file and removed immediately, shouldn't cause you any problems. The only way to do it without a tmp file would be to redirect the folded output to another file: for i in *.txt ; do fold -w 1 $i > $i".folded"; done. That, however, will double the number of files and I would not recommend it. –  terdon Aug 17 '12 at 15:25
    
Okay. All part of the learning curve. :) –  Frank_Zafka Aug 17 '12 at 15:27
    
You can optimize it if you choose the path for sillytmpfile to be on a ramdisk. On Linux this is usually /tmp, /run/shm maybe others, check with mount | grep tmpfs. –  Thor Aug 17 '12 at 16:09
add comment

sed might also be an option, it handles the temporary file issue internally:

for i in *.txt ; do
  sed  -i 's#.#&\n#g' $file
done
share|improve this answer
    
Interesting. I will one day get around to understanding sed. ;) –  Frank_Zafka Aug 17 '12 at 16:17
    
Still creates a tmp file though. And my guess is it will take slightly longer since it has a regex to evaluate and will search the entire line for it. –  terdon Aug 17 '12 at 16:49
1  
Yes, it is definitely slower, Try this with both fold and sed... time printf '%sabcdef\n' {1..1000000} |fold -w 1 >/dev/null ... Also the output is different because of the way in which original newlines are handled. –  Peter.O Aug 17 '12 at 19:52
    
@PeterO: Around 6 times slower by my measurements, but I do not get any difference in output. –  Thor Aug 17 '12 at 23:35
    
Maybe it is a version issue. Here are my commands and results of wc line counts: ... fold (GNU coreutils) 7.4 printf '%sabcdef\n' {1..1000000} |fold -w 1 |wc -l # -> 11888896 ... GNU sed version 4.2.1 printf '%sabcdef\n' {1..1000000} |sed 's#.#&\n#g' |wc -l # -> 12888896 –  Peter.O Aug 18 '12 at 3:40
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.