grep sed and a loop


 
Thread Tools Search this Thread
Top Forums UNIX for Dummies Questions & Answers grep sed and a loop
# 1  
Old 05-10-2011
grep sed and a loop

Smilie

I have a requirement to search a log file that never rotates for certain values. If I find them I pipe them to a another file. To log file is constanyl being appened with new lines and never rotating Easy so far.

The problem is I dont want to pipe out matches already seen before. One thing I tried was to use sed to put a # at the beginning of each line as it is read. Then the grep would ignore lines starting with #

My problem is I can get it to just add # to the unread lines, it adds another to all lines so each time the log is read so the earliest entries have loads of * infront of them.

I was tryin gto get it to ignore liens with # and then to a for loop for any the new lines e.g. for any not starting with # search for the string and add # to the front. This way is would only add # to lines that dont have one.
Here i swhat I was working with but just cant get that loop to work on lines not starting with #

Any help would be a awesome.

grep -v '^#' test.log | grep "Can not load CRL" This line ignores lines starting with # and greps the rest for "Can not load CRL"

sed 's/^/#/g' test.log > testnew.log The line adds the # to the front and creates output file testnew.log I want it to only add # to lines without a # already

mv testnew.log test.log This line renames\overwrites testnew.log and to test.log If anyone knows how i can write directly to the original file instead of having to write a new file and then overwrite the original would be great as well
# 2  
Old 05-10-2011
It sounds like you're working with a daemon's log file and if so you'll need to be careful. If you overlay the open log file, you'll stop seeing updates to the file as you will have unlinked the open file from the directory and replaced it with a static file that you marked up with hash (#) signs.

I think you have two choices:

1) use tail -f to read the log file and pipe the output through grep or awk to do what you need. This is probably easiest.

2) if your log file has timestamps then you can run your search periodically. With each run save the last time stamp in the log file, tuck it away in a /tmp file or something, and only process messages in the log that have a timestamp greater than the last one saved.

Small sample of using tail:
Code:
tail -f /var/log/foo | grep "Can not load CRL"  >capture-file

# 3  
Old 05-11-2011
while i appreciate your response agama im afraid im ust not that knowledgable enough to figure out how to achieve what your suggesting, most specifically how to read the last date\time, tuck it away, and then use that for the next run of the script. Would reallly appreicate if if you educate me a little Smilie
# 4  
Old 05-12-2011
Here is a simple example of how to process a log file and save the last line for reference on the next run. It uses the entire last line from the log as the reference point, rather than a date/time stamp. Less efficient, but more accurate. I'm sure there are other ways to make this more efficient, but this might help get you started.

It does run in Kshell. Should run in bash, but for several reasons I prefer Kshell and didn't test it under bash, so beware if you want to use this as a bash script.

Code:
#!/usr/bin/env ksh


logf=$1                 # log file to suss; supplied as parameter on cmd line
pat=$2                  # pattern to search log for
this=${0##*/}           # base name of script
lastf=/tmp/$this.data   # file where we tuck our last found line away for next time

if [[ -z $logf || -z $pat ]]        # error if logfile name or pattern isn't supplied
then
    echo "usage: $0 log-file-name pattern"
    exit 1
fi

if [[ ! -s $lastf ]]    # no last run data; must check all lines from log
then
    need_all=1          # this will cause us to check for pattern straight away
fi

# parse the log file writing, to stdout, any matches that haven't been seen yet
# The last line seen is written to the last data file for next time.
#
awk  -v snarf=$need_all -v lastf=$lastf -v pat=$pat '
    BEGIN {
        if( !snarf )                # not in check all mode, must find last data
        {
            getline < lastf;
            last_data = $0;
            close( lastf );
        }
    }

    snarf {                         # need all, or found the last line from prev run
        if( match( $0, pat ) )      # if it contains the pattern, print it to stdout
            print;
        new_last = $0;              # save the last line we saw
        next;                       # go to next input line (skip remaining awk code)
    }

    {       # not snarfing yet, check to see if this is the last line we saw before
        snarf = $0 == last_data;    # start snarfing if it matches
        # tricky way of saying:
        # if( $0 == last_data)
        #     snarf = 1;
    }

    END {
        if( new_last )
            printf( "%s\n", new_last) >lastf;   # save our last observed line in the data file.
    }
' <$logf

exit $?           # return the exit code that awk returned with

The one thing this script doesn't do is to deal with the case where the log file has been rolled off. In this case the data file would be non-empty, but we'd need to start checking for the pattern at the start of the log rather than after the previous marker is encountered.

The easy solution to this is to remove the last data file when the log is rolled. If that's not possible, then additional code will be needed to detect this condition; beyond my few minutes to spend answering questions tonight -- sorry.

If you need some info about awk, this is a decent set of doc:
Awk - A Tutorial and Introduction - by Bruce Barnett
and there are other posts on this forum that link other sites.

Hope this helps.
 
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Ps ax with grep in loop

Hello, I have built the following script to check if processes supplied by the argument are running or not. #!/bin/bash PROCLIST=$1 PROCESS="0" ERROR_PROCS="" IFS='+' read -ra ADDR <<< "$PROCLIST" for PROC in "${ADDR}"; do if ; then PROCESS=1 ... (9 Replies)
Discussion started by: nms
9 Replies

2. UNIX for Beginners Questions & Answers

Grep command in a loop

Hello - I am running a script that is outputting to a log. Let call it output.log I would like to monitor that log until the line "Build Successful" is found. I think I would need to use the grep command. How would I do that in a loop? Thanks Marty (1 Reply)
Discussion started by: MSpeare
1 Replies

3. Homework & Coursework Questions

GREP loop

Use and complete the template provided. The entire template must be completed. If you don't, your post may be deleted! 1. The problem statement, all variables and given/known data: I need to search through the users home directories for keywords, display them. The code listed below will show... (7 Replies)
Discussion started by: jcllns1
7 Replies

4. Red Hat

using grep in a while loop

Hello everybody, I have been searching it, but it seems I am unable to find the correct information, that s why I am asking you guys, hoping somebody get an idea. Here is my problem : I want a script to loop until a string is identified in a log file. Here is the script : #!/bin/sh... (5 Replies)
Discussion started by: guyiom
5 Replies

5. Shell Programming and Scripting

Help on grep in a do while loop

So this is what I'm trying to do: I have a file called registry.txt which has a list of registry entries I want to search for. I have another file called inctrl.txt on which I want to perform the search on. Here's the example contents of registry.txt SOFTWARE\Microsoft\Security... (3 Replies)
Discussion started by: r4v3n
3 Replies

6. Shell Programming and Scripting

Using grep within a while loop

Hi all, I have the below script to get input but i cannot get grep to work. input1.txt AAAAAAAAG input2.txt >gi|184009.1| LEAFY-like |AAAAAAAAGSGGGDHLPY However, when i use grep -f input1.txt input2.txt i cannot get any output matches (note that the match is underlined). Is it... (8 Replies)
Discussion started by: turkishvan
8 Replies

7. Shell Programming and Scripting

grep within while read loop

I have a key file $ cat klist 5 N:8855 CASA VERDE ROAD :32827 :ORLAND 5 N:585 MOLLY LANE :30189 :WOODST 5 N:320 NINA ROAD :32304 :TALLAH and a data file, see example of the line below: N:RT 15 & N 7TH STREET :17837 :U SAVE I need to search by key (2nd field) from klist... (6 Replies)
Discussion started by: migurus
6 Replies

8. Shell Programming and Scripting

How to get lines started with matched strings using sed or grep for loop?

I have a huge file and want to separate it into several subsets. The file looks like: C1 C2 C3 C4 ... (variable names) 1 .... 2 .... 3 .... : 22 .... 23 .... I want to separate the huge file using the column 1, which has numbers from 1 to 23 (but there are different amount of... (8 Replies)
Discussion started by: AMBER
8 Replies

9. UNIX for Dummies Questions & Answers

grep -v while loop

alist contain: a b c d e blist contain: a b c the code: #!/usr/bin/ksh cat blist | while read line do grep -V "$line" alist > data done (8 Replies)
Discussion started by: bobo
8 Replies

10. Shell Programming and Scripting

grep in a loop

Hi , I am trying a script which takes user input userid . I am stuck how to check whether that is a valid user id or not in the audit log files. My code is : cd $CCP_AUDIT cat * > /export/home/$USR/l***/files echo "UserId:\c" read UserId #Date Function echo "DATE : \c" read xxx I... (7 Replies)
Discussion started by: gundu
7 Replies
Login or Register to Ask a Question