Sunday, June 27, 2010

Insert text at top of file in UNIX


Purpose : Insert text at the top and bottom of a file in UNIX.

I had a lot of .in extension files in my current working directory.

One of them:

$ cat a.in
k|1|4|rty|3.4|67|1
k|2|4|rty|1.4|67|1
k|3|4|rty|3.7|62|2

Required: I had to insert two lines at the top of each files and a line at the bottom of each files.

e.g. After modification above file should look like this:

$ cat a.in
h1|t|4
h2|r|0
k|1|4|rty|3.4|67|1
k|2|4|rty|1.4|67|1
k|3|4|rty|3.7|62|2
#End

Solutions:

Unix 'Sed' utility is suitable for adding/appending, changing or inserting lines to files. You can refer one of my earlier post on this.

The bash script using 'sed':

#!/bin/sh

FILES=$(echo *.in)

for file in $FILES
do
echo "Modifying file : $file"

sed '1i\
h1|t|4' $file | sed '2i\
h2|r|0' | sed '$a\
#End' > $file.tmp

mv $file.tmp $file
done

With newer version of 'sed', the use of temporary files in the above bash script can be avoided by using '-i' option. Please refer example

-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if extension supplied)

A plain bash script without using 'sed' utility would be something like this:

for file in $(ls *.in)
do
echo "Modifying file : $file"
echo "h1|t|4" >> $file.tmp
echo "h2|r|0" >> $file.tmp
cat $file >> $file.tmp
echo "#End" >> $file.tmp
mv $file.tmp $file
done

Awk way of inserting a line of text in any line number (say insert text 'first line' as line number 1 of file.txt)

$ awk 'NR==1{print "first line"}1' file.txt


A related post:

- UNIX - add text in the middle of a file using awk in bash

3 comments:

Unknown said...

If it was a constant header and trailer why not use cat for the whole thing?

1. Create header.txt and trailer.txt
2. Modify loop over *.in to be 'cat header.txt $file trailer.txt > $file.tmp';mv $file.tmp $file
3. Done.

Anonymous said...

Even simpler would be:
sed -i ’1i Prepended line’ /tmp/newfile

Source: www.cyberciti.biz/faq/bash-prepend-text-lines-to-file/#comment-38625

Anirudh said...

No need to invoke sed multiple time.
Single call does it (for bourne)

sed -e '
1i\
h1|t|4\
h2|r|0
$a\
#End
' <$file>$file.tmp

© Jadu Saikia www.UNIXCL.com