LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-03-2013, 04:36 AM   #1
veda92
LQ Newbie
 
Registered: Jul 2013
Posts: 8

Rep: Reputation: Disabled
extract lines from log file using different parameters


Hi,
I am an intern, very new to linux and told to write a program where certain parameters entered, extracts information from different files
In /var/log there are router,route,routers and route.1,.2,.3 similarly with others
the file of the following pattern:

Jul 3 14.38.53 10.85.521 1230: Jul 3 14.32.03 %link updown:interface has turned down
Jul 3 14.35.65 25.65.897 5698: jul 3 08.26.35 %duplex mismatch tunnel 10

Now column 1 refers to month then date,time ip address,then the time and date when the kind of errors had occured.
If one were to give i/p as some ip address or error "duplex mismatch" ,o/p should have all the lines containing the ip address or error in a different file.
I don't know how to go about it should I use awk to convert them to fields and use field variable in grep? If not the script atleast someone could please suggest how do i go about it.
 
Old 07-03-2013, 05:42 AM   #2
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,359

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
Here's a good cli tutorial http://rute.2038bug.com/index.html.gz.

Are you sure about what you've been told '10.85.521 1230' doesn't look like an IP address.

In general, grep would probably do eg
Code:
grep -E 'pattern1|pattern2' filename
 
Old 07-03-2013, 04:41 PM   #3
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
This sounds a bit homework-like to me, so I'd hesitate to give any exact solutions.

In general though, grep is a fairly simple program that pulls whole lines that contain a given regular expressions pattern somewhere in them. It's very fast and efficient, but limited to whatever regex you can devise. If it's possible to extract the lines you want with grep, then consider using it first.

awk is a much more powerful and feature-rich text processing scripting language. If you need to do fine-tuned matches, including matching sub-fields and making numerical comparisons and alterations, and re-formatting the output, then that's the one you want to use.
 
Old 07-04-2013, 12:12 AM   #4
veda92
LQ Newbie
 
Registered: Jul 2013
Posts: 8

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by chrism01 View Post
Here's a good cli tutorial http://rute.2038bug.com/index.html.gz.

Are you sure about what you've been told '10.85.521 1230' doesn't look like an IP address.

In general, grep would probably do eg
Code:
grep -E 'pattern1|pattern2' filename
thanks for the link its was informative.I can't use pattern its variable also the filename is variable here and the result ought to be printed on another page
 
Old 07-04-2013, 12:30 AM   #5
descendant_command
Senior Member
 
Registered: Mar 2012
Posts: 1,876

Rep: Reputation: 643Reputation: 643Reputation: 643Reputation: 643Reputation: 643Reputation: 643
Code:
grep -E '$1|$2' $3 > $4
 
1 members found this post helpful.
Old 07-05-2013, 12:14 PM   #6
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Quote:
Originally Posted by veda92 View Post
I can't use pattern its variable also the filename is variable here and the result ought to be printed on another page
You can, you just have to get the quotes right. Variables will only expand inside double quote marks. Single quotes make everything literal.

Code:
var1=foo
var2=bar
var3=/path/to/inputfile.txt
var4=/path/to/outputfile.txt

grep -E "$var1|$var2" "$var3" >"$var4"
It's vital in scripting to understand how the shell handles arguments and whitespace. See these links:

http://mywiki.wooledge.org/Arguments
http://mywiki.wooledge.org/WordSplitting
http://mywiki.wooledge.org/Quotes
 
1 members found this post helpful.
Old 07-07-2013, 05:23 AM   #7
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
Fgrep would be helpful. And you could use this pattern to extract lines from multiple files along with multiple keywords:
Code:
fgrep -e keyword1 -e keyword2 -e keyword3 ... -- file1 file2 file3
In bash you could make use of read -a to get keywords:
Code:
#!/bin/bash
read -a KEYWORDS
Then process the contents of KEYWORDS to be usable by fgrep:
Code:
PATTERNS=()
for A in "${KEYWORDS[@]}"; do
    PATTERNS=("${PATTERNS[@]}" -e "$A")  ## PATTERNS+=(-e "$A") for newer shells but with less compatibility.
done
From there you can now call fgrep.
Code:
fgrep -H "${PATTERNS[@]}" -- "$@"  ## "$@" should hold the files passed as an argument to the script; -H makes sure that the filename is shown even with single files
And the complete form of it would be:
Code:
#!/bin/bash
read -a KEYWORDS
PATTERNS=()
for A in "${KEYWORDS[@]}"; do
    PATTERNS=("${PATTERNS[@]}" -e "$A")
done
fgrep -H "${PATTERNS[@]}" -- "$@"
If you want, you could also let your script accept both keywords and files as arguments but are separated with -- keyword.
Code:
#!/bin/bash
PATTERNS=()
FILES=()
while [[ $# -gt 0 ]]; do
    case "$1" in
    --)
        shift
        while [[ $# -gt 0 ]]; do
            FILES=("${FILES[@]}" "$1")
            shift
        done
        ;;
    *)
        PATTERNS=("${PATTERNS[@]}" -e "$1")
        ;;
    esac
    shift
done

if [[ ${#FILES[@]} -eq 0 ]]; then
    echo "No file was entered."
    exit 1
elif [[ ${#PATTERNS[@]} -eq 0 ]]; then
    echo "No pattern was entered."
    exit 1
fi

fgrep -H "${PATTERNS[@]}" -- "${FILES[@]}"
And run the command like:
Code:
[bash] script[.sh] abc def ghi jkl -- /var/log/x /var/log/y
Lastly in a more advanced manner, you could use exec to call fgrep so that you could just replace the shell's process with the command.
Code:
exec fgrep -H "${PATTERNS[@]}" -- "${FILES[@]}"
With this we assume that you wouldn't call the script with . or source which is never likely is it?

If you find the output with long lines hard to read, you could use less -S:
Code:
... | less -S

Last edited by konsolebox; 07-07-2013 at 05:26 AM.
 
Old 07-07-2013, 09:36 PM   #8
veda92
LQ Newbie
 
Registered: Jul 2013
Posts: 8

Original Poster
Rep: Reputation: Disabled
thanks it worked
 
Old 07-07-2013, 09:39 PM   #9
veda92
LQ Newbie
 
Registered: Jul 2013
Posts: 8

Original Poster
Rep: Reputation: Disabled
Smile

thanks kconsole it worked and helped another problem as well
 
Old 07-07-2013, 11:44 PM   #10
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
You're welcome. There is also one thing. You can add -i as an option to fgrep to ignare case when searching with keywords.
Code:
fgrep -H -i "${PATTERNS[@]}" -- "${FILES[@]}"
And you can also make your script parse it to make it optional.
Code:
#!/bin/bash
PATTERNS=()
FILES=()
DASHI=()
while [[ $# -gt 0 ]]; do
    case "$1" in
    --)
        shift
        while [[ $# -gt 0 ]]; do
            FILES=("${FILES[@]}" "$1")
            shift
        done
        ;;
    -i)
        DASHI=("-i")
        ;;
    *)
        PATTERNS=("${PATTERNS[@]}" -e "$1")
        ;;
    esac
    shift
done

if [[ ${#FILES[@]} -eq 0 ]]; then
    echo "No file was entered."
    exit 1
elif [[ ${#PATTERNS[@]} -eq 0 ]]; then
    echo "No pattern was entered."
    exit 1
fi

fgrep -H "${DASHI[@]}" "${PATTERNS[@]}" -- "${FILES[@]}"
So you could use it like:
Code:
[bash] script[.sh] -i abc def ghi jkl -- /var/log/x /var/log/y
---- EDIT ----

Come to think of it we no longer have to loop through with the files.
Code:
#!/bin/bash
PATTERNS=()
FILES=()
DASHI=()
while [[ $# -gt 0 ]]; do
    case "$1" in
    --)
        FILES=("${@:2}")
        break
        ;;
    -i)
        DASHI=("-i")
        ;;
    *)
        PATTERNS=("${PATTERNS[@]}" -e "$1")
        ;;
    esac
    shift
done

if [[ ${#FILES[@]} -eq 0 ]]; then
    echo "No file was entered."
    exit 1
elif [[ ${#PATTERNS[@]} -eq 0 ]]; then
    echo "No pattern was entered."
    exit 1
fi

fgrep -H "${DASHI[@]}" "${PATTERNS[@]}" -- "${FILES[@]}"
Or even yet no longer use the FILES variable at all and just use "$@", but now it's just a preference.

Last edited by konsolebox; 07-07-2013 at 11:52 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Extract a Sequence of lines from a Text File sparker1970 Linux - General 2 04-04-2012 09:56 PM
How to extract lines from file using AWK keenboy Linux - General 7 08-05-2010 08:29 AM
Extract uncommented lines from a file aarav2306 Linux - Newbie 6 07-11-2009 11:27 AM
Extract lines NOT on a block of text from a file Renan_S2 Programming 3 10-05-2008 04:14 PM
how to extract certain lines from a log file Avatar Linux - Newbie 3 02-11-2005 09:51 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:08 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration