1

I'm trying to write a script which will analyse a log file, i want to give the user the option to enter a pattern and then print any line which matches this pattern in a specific column (the fifth one) the following works from the terminal

awk ' $5=="acpid:" {print$0}' *filename*

ok so above im trying to match "acpid:" this works fine but in the script i want to be able to allow multiple entries and search for them all, the problem is i'm messing up the variable in the script this is what i have:

echo "enter any services you want details on, seperated by spaces"
read -a details
for i in ${details[@]}    
do 
        echo $i
        awk '$5 == "${i}" {print $0}' ${FILE}
done

again if i directly put in a matching expression instead of the variable it works so i guess my problem is here any tips would be great

UPDATE

So im using the second option suggested(shown below) by @ghoti as it matches my log file slightly better however im not having any luck with multiple entries. ive added two lines to illustratre the results im getting these are echo $i and echo "finish loop" as placed they should tell me what input the loop is currently on and that im leaving the loop

    'read -a details
    re=""

    for i in "${details[@]}"; do
    re="$re${re:+|}$i"

     echo $i
     echo"finish loop"
    done

    awk -v re="$re" '$5 ~ re' "$FILE" `

When i give read an input of either "acpid" or "init" seperately a perfect result is matched, however when the input is "acpid init" the following is the output

acpid init
finish loop

What im seeing from this is that the read is taking the both words as one entry and then the awk is searching but not matching them (as would be expected). so why is the input not being taken as two separate entries i had thought the -a option with read specified that words separated by a space would be placed into separate elements of the array. perhaps i have not declared the array correctly?

Update update

ok cancel the above update like i fool i'd forgotten that id chaged IFS to \n earlier in the script changed it back and bingo !!!

Many thanks again to @ghoti for his help!!

1 Answers1

1

There are a few ways that you could do what you want.

One option might be to run through a for loop for each word, then apply a different call to awk, and show the results sequentially. For example, if you entered foo bar into the $details variable, you might get a list of foo matches, followed by a list of bar matches:

read -a details
for i in "${details[@]}"; do
  awk -v s="$i" '$5 == s' "$FILE"
done

The idea here is that we use awk's -v option to get each word into the script, rather than expanding the variable inside the quoted script. You should read about how bash deals with different kinds of quotes. (There are also a few Stackoverflow questions on the topic, here and here and elsewhere.)

Another option might be to construct a regular expression that searches for all the words you're interested in, all at once. This has the benefit of using a single run of awk to search through $FILE:

read -a details
re=""
for i in "${details[@]}"; do
  re="$re${re:+|}$i"
done
awk -v re="$re" '$5 ~ re' "$FILE"

The result will contain all the interesting lines from $FILE in the order in which they appear in $FILE, rather than ordered by the words you provided.

Note that this is a fairly rudimentary search, without word boundaries, so if you search for "foo bar babar", you may get results you don't want. You can play with the regex yourself, though. :)

Does that answer your question?

Community
  • 1
  • 1
ghoti
  • 45,319
  • 8
  • 65
  • 104
  • +1 Dammit, I was going to write all that and saw you already made a head start. Deleting mine! `:)` – jaypal singh Feb 27 '14 at 18:22
  • 1
    Thanks. You've beat me to the punch on a few as well. ;-) – ghoti Feb 27 '14 at 18:24
  • Thanks for the great detailed answer i've tried both and each matches the user entry perfectly but when i try enter more that one variable neither option does anything. prob lem with the read statement maybe? – user3361632 Feb 27 '14 at 18:54
  • The first one works for me with multiple entries, but I just fixed an error in the second one inside the `for` loop. Give it another shot, or perhaps [append an update to your question](http://stackoverflow.com/posts/22076186/edit) that shows what you tried and what your results were. – ghoti Feb 27 '14 at 21:08
  • thanks @ghoti i had changed IFS and forgotten to change it back Duh! – user3361632 Feb 28 '14 at 16:34