Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

newbie question re grep ? 2

Status
Not open for further replies.

kenred

Technical User
Aug 16, 2001
58
GB
Only new to Unix so this is probably a daft question.
Anyway is it possible to search a file for the occurence of a text string, and display that line and the next line as well.

 
#!/usr/bin/ksh
FILE=[full path and your file name here ex: /tmp/file]

TEXT="error" # text you want to look for

PRINT_NEXT_LINE="false"

cat $FILE while read LINE
do
if [ "$PRINT_NEXT_LINE" = "true" ]
then
echo $LINE
PRINT_NEXT_LINE="false"
else
TEST=`grep $TEXT $LINE`
if [ ${#TEST} -gt 0 ]
then
FOUND_ONE="true"
echo $LINE
PRINT_NEXT_LINE="true"
else
FOUND_ONE="false"
fi
fi
done
 
oops! found a typo - missing pipe after cat $FILE

#!/usr/bin/ksh
FILE=[full path and your file name here ex: /tmp/file]

TEXT="error" # text you want to look for

PRINT_NEXT_LINE="false"

cat $FILE|while read LINE
do
if [ "$PRINT_NEXT_LINE" = "true" ]
then
echo $LINE
PRINT_NEXT_LINE="false"
else
TEST=`grep $TEXT $LINE`
if [ ${#TEST} -gt 0 ]
then
FOUND_ONE="true"
echo $LINE
PRINT_NEXT_LINE="true"
else
FOUND_ONE="false"
fi
fi
done
 
the script could also be changed so the file name
could be passed as an argument

FILE_NAME="$1"

i am making the assumption that the script name
is "find_errors" but you can call it whatever you like.
that way you could execute the script like this:

./find_errors /tmp/logfile

in this case $1 would be equal to "/tmp/logfile"

Robert

Robert G. Jordan

Robert@JORDAN200.com
Unix Admin, United Airlines
 
Robert
Thank you for your reply, I have done what you said but it scrolls through the log file from start to finish.
I am using a Bourne shell, does this make a difference.

Sorry if I sound a bit thick, but I am new to this

Ken
 
Are you able to use the k shell?
I wrote this script in theory and assumed it would work.
Let me do some testing and get back to you.

Robert
Robert G. Jordan

Robert@JORDAN200.com
Unix Admin, United Airlines
 
Robert

I can't use the K shell.

It appears to assume that the PRINT_NEXT_LINE is evaluating to true all the time, and therefore just outputs the whole file.
I have put some echo statements in, in various places and have found that it doesnt seem to get past the first else statement.

Thanks for your help so far.

Ken
 
Yep, I forgot to test :-(
Think I fixed the bug - Here ya go.

For testing I made the following file.

# cat /tmp/error_test.txt
this is line 1 error
this is line 2
this is line 3
this is line 4
this is line 5 error
this is line 6

Here is the new script:

#!/usr/bin/ksh

FILE_NAME=/tmp/error_test.txt # modify this and put your file name here.
# if you always have to specify the file name,
# the line above can be removed from this script

# if you provide the file name as an argument
# the default file name above will not be used.
if [ ${#1} -gt 0 ]
then
FILE_NAME="$1"
fi

TEXT="error" # text you want to look for

PRINT_NEXT_LINE="false"

cat $FILE_NAME|while read LINE # loop that reads every line of log file
do
if [ "$PRINT_NEXT_LINE" = "true" ]
then
echo "$LINE" # this the 2nd line
PRINT_NEXT_LINE="false"
else
TEST=`echo $LINE|grep -i "$TEXT"`
if [ ${#TEST} -gt 0 ]
then
FOUND_ONE="true"
echo "$LINE" # this is the first line
PRINT_NEXT_LINE="true"
else
FOUND_ONE="false"
fi
fi
done


This is the output from the script
# ./test
this is line 1 error
this is line 2
this is line 5 error
this is line 6

:)

Robert

Robert G. Jordan

Robert@JORDAN200.com
Unix Admin, United Airlines
 
Robert,

Sorry to be a pain.
I have worked out how to get into the k shell, you just type ksh at the prompt!! doh.

Still cant get it to work, I have copied exactly what you said, I also created the file error_test.txt, it still outputs all lines in the file, its driving me mad.

I have sort of worked out that its the line
TEST='echo $LINE|grep -i "$TEXT"'
if i echo $TEST straight after in the script it outputs
echo $LINE|grep -i "$TEXT

I have tried taking out quotes, puting them in different places etc.. but to no avail.

Any ideas, sorry to keep bugging you with this, thanks for your help so far.

Is this script writing something that you can teach yourself from books, or does it require tuition ??
 
Excellent it works HURRAHH

Stan Hubble
Dont think i've ever used that backticks key in my life.

Robert
Many thanks for your patience with a new to unix person.

Ken
 
No problem. I still consider myself intermediate.
I have mostly learned from practice, looking at
other people's scripts, asking friends for help
and reading books. The book I have now
"The Complete Reference UNIX" from OSBORNE
has two chapters on shell programming
which are pretty easy to follow.

Sounds like you are manualy typing this in, Kenred.
You should be able to paste this into your vi editor.

Assuming you're browsing the net using windows...
Just highlight all the text for the script,
ctrl-c to copy, telnet to your unix machine
and open a vi session, press i to insert,
and you should be able to right-click or middle-click
to paste the text into your vi session depending
on your telnet program.

Another option is to paste it into a windows notepad
file, save it, and ftp it to your unix machine.
Make sure you type "ascii" after you are logged in with ftp
before you "put" the file.

Robert
Robert G. Jordan

Robert@JORDAN2000.com
Unix Admin, United Airlines
 
Robert

After reading your last reply I did copy and paste it into the editor, and guess what it worked straight away, Stupid of me not to do it before.

Just one more question, in the line
if [ ${#TEST} -gt 0 ]
why the curly brackets and what does the # mean.

Being naive I thought that the # was used for comments.

Yes another silly question

Ken
 
I still get confused about the the curly braces,
but they effect the way the command is evaluated
by the shell. In this example there is also a # sign.

In this case the number of characters is returned.
Here's an example:
NAME=Ken
NAME_LENGTH=${#NAME}
echo $NAME_LENGTH
3

In the script above there is a grep statement.
If the grep statement finds a match,
TEST will have a length greater than 0.
Basically a test to find out if grep had
one or more matches.

Robert




Robert G. Jordan

Robert@JORDAN2000.com
Unix Admin, United Airlines
 
I think the original problem could be done easy with awk:
[tt]
awk '/yourtexthere/ {print; next line; print}' /your/file/here
I hope it works...
Unix was made by and for smart people.
 
Wow! This would be a great shortcut,
but I couldn't seem to get it to work.
Could you check the syntax and let me know?

Thanks,

Robert

# awk '/error/ {print; nextline; print}' /tmp/error_test.txt
this is line 1 error
awk: A statement occurred that is not valid.

The input line number is 1. The file is /tmp/error_test.txt.
The source line number is 1.

Here's the file I am running the command against:# cat /tmp/error_test.txt
this is line 1 error
this is line 2
this is line 3
this is line 4
this is line 5 error
this is line 6


Robert G. Jordan

Robert@JORDAN2000.com
Unix Admin, United Airlines
 
I had no luck with the awk example, probably my version of awk. Here is a way with sed. Don't forget to quote search text with spaces and escape special characters.

#! /usr/bin/ksh
SEARCH="$1"
shift
sed "
/.*${SEARCH}.*/{
N
b
}
d
" "$@"
# end of script

Cheers
 
The awk program you need is
[tt]
/error/ {print; getline; print}
[/tt]
Hope this helps. CaKiwi
 
To search a file for certain text you could also run the following command :

find {path} -exec grep -l 'filename' {} \;

and there after you could pipe to 'cut' and perhaps 'sort'.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top