#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2012
    Posts
    59
    Rep Power
    3

    Redirect STDIN in BASH script to a file?


    I am trying to get this BASH script to work. I am a newbie at BASH scripts.
    So now this script DOES NOT WORK.
    The script is supposed to take exactly three parameters, e.g.,
    $script 5 9 filename
    and print lines 5 through 9 of the file whose name is given as the third parameter.
    (The extra echo's are just debug statements.)

    Code:
    #!/bin/bash
    # simplified version of extract using single awk line
    # syntax:
    #  pl 3 7 datafile
    # to print lines 3 through 7 from datafile
    # script assumes datafile contains line-oriented text
    
    E_BADARGS=65
    
    if [ ! -n "$3" ]
    then
      echo "Usage: `basename $0`  3 7 filename"
      echo "        displays lines 3 through 7 from filename"
      exit $E_BADARGS
    fi
    echo $1
    echo $2
    echo $3
    awk 'BEGIN {i=$1; j=$2;} NR>=i && NR<=j {print}' $3
    My trouble is how do I redirect STDIN to read from the file whose name is given as the third parameter ? The awk filter does not read from the file at all as shown.
    Why doesn't the last statement in this script work as it does at the command line ?
    Am I doing something wrong? I probably overlooked something basic.
    Maybe the script needs to be structured like this?
    Code:
    while read line
    do
         print some
    done >> outfile
    I just don't know how to read from a file yet.
  2. #2
  3. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2012
    Location
    spaceBAR Central
    Posts
    229
    Rep Power
    42
    This is an example that should be helpful:

    The -v option can be used to pass shell variables to awk command:
    Code:
    root="/webroot"
    echo | awk -v r=$root '{ print "shell root value - " r}'
    In this example search file using awk as follows:
    Code:
    #!/bin/bash
    # Usage : Search word using awk for given file.
    # Syntax: ./script "word-to-search" fileToSearch
    s=$1
    i=$2
    awk -v search="$s" '$0 ~ search' "$i"
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2012
    Posts
    59
    Rep Power
    3
    Thank you. Those two examples help.

    I tried to use your technique to pass the variables to awk in my script.
    Code:
    #!/bin/bash
    # simplified version of extract using single awk line
    # syntax:
    #  extr 5 7 datafile
    # to extract lines 5 through 7 from datafile
    # script assumes datafile is line-oriented text
    
    E_BADARGS=65
    
    if [ ! -n "$3" ]
    then
      echo "Usage: `basename $0`  3 7 filename"
      echo "        displays lines 3 through 7 from filename"
      exit $E_BADARGS
    fi
    #echo
    echo $1
    echo $2
    echo $3
    i=$1
    j=$2
    k=$3
    echo $i
    echo $j
    echo $k
    #awk -v ai=$i -v aj=$j 'NR >= $i && NR <= $j {print}' "$k"
    awk -v ai="$i" -v aj="$j" ' BEGIN { echo "ai is " $ai; echo "aj is "$aj } ' "$k"
    Parameters are getting passed okay, as evidenced by the output:

    $ extr 2 3 junk
    2
    3
    junk
    2
    3
    junk

    Don't understand why neither of my two awk statements work. I"ll sleep on it and have another look tomorrow.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Mar 2006
    Posts
    2,448
    Rep Power
    1751
    User variables inside awk do not have a leading $

    What you are looking for is:
    Code:
    i=$1
    j=$2
    file=$3
    wk -v ai=$i -v aj=$j 'NR>=ai && NR <=aj {print}' $file
    You could just bypass the initial 3 variable declarations and plug the $1, $2 and $3 in directly, but I tend to think that makes things harder to follow.
    The moon on the one hand, the dawn on the other:
    The moon is my sister, the dawn is my brother.
    The moon on my left and the dawn on my right.
    My brother, good morning: my sister, good night.
    -- Hilaire Belloc
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2012
    Posts
    59
    Rep Power
    3
    {deleted dupl. post]
    Last edited by EEmaestro; August 30th, 2012 at 09:34 AM.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2012
    Posts
    59
    Rep Power
    3
    Good morning, brother.

    I see now that I had placed the $ sign in front of the variables passed to the body of the awk program -- inside its single quotes. That is a no-no. Which I now know.
    $ is the BASH way to get at the value of a variable. It doesn't generally apply to awk, despite awk's built-in variables, $0, $1, $2, etc. Thank you for helping me. The script works perfectly now.

    Code:
    #!/bin/bash
    # simplified version of extract using single awk line
    # syntax:
    #  extr 5 7 datafile
    # to extract lines 5 through 7 from datafile
    # script assumes datafile is line-oriented text
    E_BADARGS=65
    if [ ! -n "$3" ]
    then
      echo "Usage: `basename $0`  3 7 filename"
      echo "        displays lines 3 through 7 from filename"
      exit $E_BADARGS
    fi
    #Pass parameters to AWK using -v option
    i=$1
    j=$2
    k=$3
    file=$3
    awk -v ai=$i -v aj=$j 'NR>=ai && NR <=aj {print}' $file
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Mar 2006
    Posts
    2,448
    Rep Power
    1751
    Happy to help - almost all you need now is to check $1 and $2 are valid numbers (integer and positive) and that one is greater than, or equal to, the other and pass them to awk in the right order.
    The moon on the one hand, the dawn on the other:
    The moon is my sister, the dawn is my brother.
    The moon on my left and the dawn on my right.
    My brother, good morning: my sister, good night.
    -- Hilaire Belloc

IMN logo majestic logo threadwatch logo seochat tools logo