2
Feb

Cute ‘sed’ Tricks to Modify Specific Lines Within File

Here’s a cute trick to change or insert a line in a file given a line number using sed. You can pair it with grep to make it even more powerful with pattern matching.

#!/bin/sh

if [ $# -lt 1 ]; then
   echo "Usage: $0 <filename>"
   exit
fi

# Variables
#file=testfile.txt
file=$1

# First, change line number $linenum, then insert
# two spaces at the beginning of that same line
linenum=1
sed -i "${linenum}c This line was changed" $file
sed -i "${linenum}s/^/   /" $file

# Insert a line at $linenum, then insert text at 
# the end of that same line.
linenum=2
sed -i "${linenum}i This line was inserted" $file
sed -i "${linenum}s/$/ end of line/" $file

# Match a particular pattern in the file and insert a line
# directly above the first match (will need massaging for
# multiple lines, perhaps using an array)
linenum=`grep -n pattern $file | head -n1 | cut -d: -f1`
linenum_above=`echo "$linenum - 1" | bc`
sed -i "${linenum_above}i This line was inserted" $file

echo "Resulting File:"
cat $file

As usual, take a look at the man pages for sed for more information.

Feel free to donate if this post prevented any headaches! Another way to show your appreciation is to take a gander at these relative ads that you may be interested in:


There's 4 Comments So Far

  • [email protected]
    February 3rd, 2011 at 8:48 am

    A comment I received from a subscriber via email…

    sed is more powerful than you imply here. No need for grep etc.
    Instead of a specific line number one can get sed to search for lines, just
    like grep hence…..

    On Wed, 2 Feb 2011, The Linux Daily wrote:

    > # Match a particular pattern in the file and insert a line
    > # directly above the first match (will need massaging for
    > # multiple lines, perhaps using an array)
    > linenum=`grep -n pattern $file | head -n1 | cut -d: -f1`
    > linenum_above=`echo “$linenum – 1” | bc`
    > sed -i “${linenum_above}i This line was inserted” $file

    … becomes

    sed -i “/pattern/a This line was inserted” $file

    ‘a’ inserts after the line found, ‘i’ would insert before.

    However your version will do just the first line, the sed inbuilt would
    insert at every line matching “pattern”.

    It’s also useful for deleting lines that match….

    sed -i “/^#/d” script.sh

    deletes all the comments. Though in ths case I think I’d do…

    sed -i~ “/^#/d” script.sh

    To get the backup script.sh~ – just in case 🙂

    sed is indeed very nifty and useful.

    cheers
    Jim

  • [email protected]
    February 3rd, 2011 at 8:48 am

    Ha!

    Jim, You’re awesome.

    Thanks! I’m sharing with the world…

    Naturally, it seems so easy now. One of those, “now why didn’t I
    think of that” situations. haha

    Best Regards,
    Derek

  • DrewNYC
    March 11th, 2011 at 3:11 pm

    very instructive Thank you all! 🙂

  • Jason Barnett
    November 22nd, 2011 at 4:14 pm

    This was very helpful. Thanks!

Share your thoughts, leave a comment!