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 have a number of files in a directory hierarchy. For each file, I'd like to add "abcdef" to the beginning, on its own line, and "ghijkl" to the end, on its own line. For example, if the files initially contained:

# one/foo.txt
apples
bananas

# two/three/bar.txt
coconuts

Then afterwards, I'd expect them to contain:

# one/foo.txt
abcdef
apples
bananas
ghijkl

# two/three/bar.txt
abcdef
coconuts
ghijkl

What's the best way to do this?

I've gotten as far as:

# put stuff at start of file
find . -type f -print0 | xargs -0 sed -i 's/.../abcdef/g'

# put stuff at end of file
find . -type f -print0 | xargs -0 sed -i 's/.../ghijkl/g'

but I can't seem to figure out how what to put in the ellipses.

share|improve this question
    
I can’t help but notice how simple and straightforward this is in Windows: for %i in (*) do echo abcdef>t.tmp & type "%i">>t.tmp & echo ghijkl>>t.tmp & move /y t.tmp "%i" or alternately, echo abcdef>header.tmp & echo ghijkl>footer.tmp & for %i in (*) do copy /y headert.tmp+"%i"+footer.tmp "%i" & del header.tmp & del footer.tmp –  Synetech Aug 30 '12 at 15:27
    
@Synetech: Does that work recursively? –  Dennis Aug 30 '12 at 15:37
1  
@Dennis, as in for files in subfolders? No, but you can add a /r to the for loop to make it recursive. –  Synetech Aug 30 '12 at 16:41
add comment

3 Answers

up vote 2 down vote accepted

This isn't a job for sed. To add lines, just use I/O redirection.

For a single file named filename, you can do the following:

mv filename temp
(echo abcdef ; cat temp ; echo ghijkl) > filename
rm temp

To do this automatically to all files in the current directory, use find and xargs:

find -type f -print0 | xargs -0 -I % sh -c '
    mv "%" temp
    (echo abcdef ; cat temp ; echo ghijkl) > "%"
'
rm temp
share|improve this answer
    
I would suggest a tweak: (echo abcdef; cat filename; echo ghijkl) > temp;  cp temp filename;  rm temp, to retain attributes (owner and mode) on the files. –  Scott Aug 30 '12 at 16:28
    
This did the trick for me. Thanks! –  John Feminella Aug 30 '12 at 16:29
    
Ownership and permissions might get lost by simply moving the file. Good point, @Scott. But copying instead of moving might come with a great performance penalty (if the files are big), so I'd use chmod and chown with the --reference switch in this case. –  Dennis Aug 30 '12 at 16:34
add comment

If you have GNU sed available you can use the i\ and a\ constructs:

Use line addresses to apply to first and last line respectively:

find . -type f -print0 | xargs -0 sed -i -e '1i\abcdef' -e '$a\ghijkl'
share|improve this answer
    
To me this seems a more elegant, less error prone and more efficient solution than the one accepted. –  potong Sep 3 '12 at 23:30
add comment
For files in directory as file
echo "abcde" && cat file && echo "fghijk" > file
share|improve this answer
1  
This will not work for two reasons: 1. cat is not echo. It won't print abcdef but display an error. 2. Input file and output file cannot be the same. –  Dennis Aug 30 '12 at 15:18
    
Thank you :) Fixed –  patrick_corrigan Aug 30 '12 at 15:32
    
This won't work either. It writes fghijk to file and deletes all the rest! It wouldn't work with parentheses either, since cat's input and output file can't be identical. –  Dennis Aug 30 '12 at 15:33
1  
Please do not just guess as to the solution for a problem. If you don't know the solution, take a moment to research (trying this yourself isn't too time-consuming in this case) or refrain from posting guesses. –  Daniel Beck Aug 30 '12 at 15:36
    
Sorry I just got overly excited:P I'll try to control myself in future :D –  patrick_corrigan Aug 31 '12 at 13:04
add 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.