1

I have this file

127.0.0.1   localhost

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

and I want to use awk to add a line after/before the pattern 127.0.0.1. Pattern and line are bash variables.

#!/bin/bash

file="test.txt"
pattern='127.0.0.1'
line='127.0.1.1   cent.centurian.com   centurian'

awk -vpattern="$pattern" -vline="$line" '/pattern/{print;print line;next}1' "$file"

Doesn't work...

3

sed is simpler:

sed "/$pattern/a\
$line" "$file"

Output:

127.0.0.1   localhost
127.0.1.1   cent.centurian.com   centurian

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

GNU sed allows a one-liner version of the above:

sed $file -e "/$pattern/a $line"

...and to output $line before $pattern, change the a(ppend) to an i(nsert):

sed $file -e "/$pattern/i $line"
1

Close. That looks for the (literal) pattern pattern.

You need to use $0 ~ pattern to match against a variable.

$ pattern='127.0.0.1'
$ line='127.0.1.1   cent.centurian.com   centurian'
$ awk -vpattern="$pattern" -vline="$line" '$0 ~ pattern {print; print line; next} 1' $file | head -2
127.0.0.1   localhost
127.0.1.1   cent.centurian.com   centurian
  • OK, worked! Also I used $file instead of hosts as in my question. Thanks! – centurian Sep 24 '16 at 20:46
0

Before the matched line:

awk -v line='127.0.1.1   cent.centurian.com   centurian' '/127\.0\.0\.1/ \
        { printf "%s\n%s\n", line, $0; next }; 1' file.txt

After the matched line:

awk -v line='127.0.1.1   cent.centurian.com   centurian' '/127\.0\.0\.1/ \
        { printf "%s\n%s\n", $0, line; next }; 1' file.txt

  • /127\.0\.0\.1/ matches the pattern

  • If the pattern is matched, the desired formatted output is printed by printf based on whether the variable line would be before or after the matched line


Example:

$ cat file.txt                                                                                                              
127.0.0.1   localhost

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

$ awk -v line='127.0.1.1   cent.centurian.com   centurian' '/127\.0\.0\.1/ { printf "%s\n%s\n", $0, line; next }; 1' file.txt
127.0.0.1   localhost
127.0.1.1   cent.centurian.com   centurian

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

$ awk -v line='127.0.1.1   cent.centurian.com   centurian' '/127\.0\.0\.1/ { printf "%s\n%s\n", line, $0; next }; 1' file.txt
127.0.1.1   cent.centurian.com   centurian
127.0.0.1   localhost

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
  • OK worked! But I changed as: awk -vline="$line" '/127\.0\.0\.1/ { printf "%s\n%s\n", $0, line; next }; 1' $file as per question. But I want '127.0.0.1' to be a bash variable! – centurian Sep 24 '16 at 20:56
0

Just made a function that do this:

################################################################################
## Adds a line in a file.                                                     ##
#------------------------------------------------------------------------------#
# Given the arguments:                                                         #
# 1st: file                                                                    #
# 2nd: string to find                                                          #
# 3rd: line to add                                                             #
# 4th: 'b' for before, 'a' for after.                                          #
# It adds a line before or after the line containing the search string.        #
################################################################################
function addLineInFileOnString() {
   local file pattern line where tmp
   file="$1"
   pattern="$2"
   line="$3"
   where="$4"
   tmp="$( cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1 )"
   tmp='tmp.'$tmp

   if [[ $where == 'b' ]]; then
      awk -v pattern="$pattern" -v line="$line" '$0 ~ pattern {print line; print; next} 1' "$file" | tee 1>/dev/null $tmp
   elif [[ $where == 'a' ]]; then
      awk -v pattern="$pattern" -v line="$line" '$0 ~ pattern {print; print line; next} 1' "$file" | tee 1>/dev/null $tmp
   fi

   [[ -e $tmp ]] && cp "$tmp" "$file" && rm "$tmp"
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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