Unix Editing Utilities Sed and Awk

For a good reference:
UNIX Made Easy, Second Edition, John Muster and Associates
sed & awk, Dougherty & Robbins, O'Reilly

Comparing sed to vi

Sed

Using sed to substitute a pattern

Exercise:
$ cp /etc/passwd /tmp/sample

Request that sed act only on lines that meet a specified criteria

Exercise:

Deleting a line by number

Note:  sed instructions are enclosed in single quotes to avoid being interpreted by the shell.
What other command uses single quotes for the same reason?

Using the quit command to terminate sed

Exercise:

Combining sed commands

Exercise:

Transforming Characters with sed

Exercise:

Using a sed command file

Exercises:

Review

What do the following commands accomplish?
sed 's/fries/chips/g' file1

sed '/start/,$ d' file2

sed -e 's/initdefault/mychange/g' -e '/^$/ d' /etc/inittab

sed -f changes projectA

sed '/^$/q' /etc/inittab



Exercise:

Assume you have just updated your kernel and want the new kernel to be your default kernel in lilo.conf.

prompt
timeout=50
default=linux
boot=/dev/hda
map=/boot/map
install=/boot/boot.b
message=/boot/message
linear

image=/boot/vmlinuz-2.4.18
        label=linux-new
        initrd=/boot/initrd-2.4.18.img
        read-only
        root=/dev/hda1

image=/boot/vmlinuz-2.4.19
        label=linux
        initrd=/boot/initrd-2.4.19.img
        read-only
        root=/dev/hda1
 

#! /bin/bash

LOGFILE=/tmp/sedlog

if sed -e 's/label=linux$/label=linux-old/' \
       -e 's/label=linux-new/label=linux/'  \
            /tmp/lilo.conf > /tmp/lilo.conf.new ; then
          :
else
      echo Sed command failed... |tee -a $LOGFILE 2>&1
      echo Check /tmp/lilo.conf for errors... |tee -a $LOGFILE 2>&1
fi

Make your script executable

$ chmod +x /tmp/lilomod
Execute it and look at the differences between the two files
$ diff lilo.conf lilo.conf.new
What does the tee command and the redirector 2>&1 do in the above script?


Exercise:

1. Create the directory /tmp/sysconfig

$ mkdir /tmp/sysconfig
2. Copy  /etc/sysconfig/network file to /tmp/sysconfig
$ cp /etc/sysconfig/network /tmp/sysconfig
3. Create a shell script named /tmp/namehost that looks like the following:

#! /bin/bash

CUSTOM_NAME=stationXX

if  [ $CUSTOM_NAME != "" ]; then
   cp /tmp/sysconfig/network /tmp/sysconfig/network.svd
   sed '/HOSTNAME/d' /tmp/sysconfig/network \
        > /tmp/sysconfig/network.new
   mv /tmp/sysconfig/network.new /tmp/sysconfig/network
   echo "HOSTNAME=$CUSTOM_NAME" >> /tmp/sysconfig/network
fi

4. Make the script executable

$ chmod +x /tmp/namehost
5. Execute the script
$ /tmp/namehost
6. Explain what happened


Extracting a value from a line of text using sed

Extract a value on the end of a line

1. Look at the contents of /proc/cpuinfo

$ less /proc/cpuinfo
2. Extract the model name and assign it the variable name model 3. check the value of the variable model
$ echo $model
Pentium II (Klamath)
Extract a value surrounded by other text

1. look at the output of ifconfig

$ ifconfig eth0 | grep 'inet addr'
2. Extract the IP number of your machine from this output   inet addr:192.168.1.20  Bcast:192.168.1.255  Mask:255.255.255.0 3. check the value of ipaddress
$ echo $ipaddress
192.168.1.20
Saving user input to a file using sed
  • many lines

  • $ sed -e 's/^//' > /tmp/input
    stuff
    more stuff
    my input lines here
    ^d
    $ cat /tmp/input
    stuff
    more stuff
    my input lines here
     

  • The more familiar way

  • $ cat > /tmp/input
    stuff
    more stuff
    my input lines here
    ^d
     

  • one line

  • $ sed -e 's/^//' -e 'q' > /tmp/input
    one line of input
    $ cat /tmp/input
    one line of input
     

  • The more familiar way

  • $ echo "one line of input" > /tmp/input

    Awk Awk does its work by selecting records based on a pattern or field, and then performing some action on the selected record.

    Change the field delimiter

    Relational and Boolean Operators in Awk

    == equal to
    != not equal to
    < less than
    <= less than or equal to
    > greater than
    >= greater than or equal to
    && and
    || or
    ~ a match for (regular expression)
    !~ not a match for (regular expression)

    Selecting Multiple Patterns with awk

    $ awk '/uucp/ || /daemon/ {print}' /etc/passwd

    Selecting lines by field value

    $ ls -l /etc | awk '$5 < 1024'

    Match if two conditions are met using &&

    Using logical negation

    Using Special Variables in Awk Exercise:

    What does the following commands return?

    $ ls -l | awk '{print $NF}'
    $ ls -l | awk '{print NF}'
    $ ls -l | awk '{print NR}'

    Extracting records (lines) from a file

    Homework:
    1. Write a command line  using sed and awk that prints the name of any partition (not device) on your system who's capacity is at 95% or greater. Make sure your command line works. Test it!

    One possible solution:

    $ df | sed 's/%//'| awk '$5>95 && $5 ~/[0-9]/ {print $6,$5"%"}'

    Be prepared to write a similar command next Wednesday in class for a quiz.