LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 07-28-2011, 09:28 PM   #1
Lagos
LQ Newbie
 
Registered: Jun 2010
Location: Las Cruces, NM
Distribution: MAC OSX 10.6.4 / Fedora 12
Posts: 11

Rep: Reputation: 8
awk and shell expansion


hello:

I have a problem that I've solved but I'd like to better understand why it worked.

The particulars are as follows:

I have a log_file of the following form:

++++++++++
data
data
data
data
2011-07-27
data
data
++++++++++
data
data
2011-07-28
data
++++++++++

"++++++++++" ---> is my record separator

Objective: mail the record for a specific date.

Approach:

#!/bin/bash
i=`date +%F`
awk 'BEGIN{FS="\n"; RS="++++++++++"} /'$i'/ {print $0}' log_file >/tmp/alert
mail -s "mydata" root@localhost < /tmp/alert


In my inbox I find

data
data
2011-07-28
data


Excellent.

Now, trying to do things in one fell swoop why wouldn't the following work?

awk 'BEGIN{FS="\n"; RS="++++++++++"; "date +F%"|getline dateVal} /dateVal/ {print $0}' log_file >/tmp/alert

Can someone help me understand:

1. Why this second option does not work?

2. How awk can actually use the correct value for $i in the first script when it is enclosed in single quotes? I previously thought that single quotes kill any and all special meaning. This is as literal as you can get? How is the expansion working correctly in this case? Is there something special about using the / /, which is specific to regex?

Thanks.

Last edited by Lagos; 07-28-2011 at 09:34 PM.
 
Old 07-29-2011, 01:31 AM   #2
sag47
Senior Member
 
Registered: Sep 2009
Location: Raleigh, NC
Distribution: Ubuntu, PopOS, Raspbian
Posts: 1,899
Blog Entries: 36

Rep: Reputation: 477Reputation: 477Reputation: 477Reputation: 477Reputation: 477
First off ` /= '. A back tick (`) which is part of the tilde (~) key above the tab key is not a single quote ('). You are right in saying that single quotes change the meaning of a command where echo "$PATH" and echo '$PATH' give two different outputs.

I'm no awk expert but I don't believe you can simply pipe the output of a command like that from within awk. To execute commands you have to use the system function for example system("date"). As for the rest I'll defer someone else who would know better.

By the way in your awk command the $i is not enclosed by single quotes. It is outside of them. Below I have highlighted the quoted text.

awk 'BEGIN{FS="\n"; RS="++++++++++"} /'$i'/ {print $0}' log_file >/tmp/alert

You might be able to do something like this.
Code:
#!/bin/bash
awk 'BEGIN{FS="\n"; RS="++++++++++"} /'`date +%F`'/ {print $0}' log_file >/tmp/alert
mail -s "mydata" root@localhost < /tmp/alert
or even better since there's no tmp file
Code:
awk 'BEGIN{FS="\n"; RS="++++++++++"} /'`date +%F`'/ {print $0}' log_file | mail -s "mydata" root@localhost

Last edited by sag47; 07-29-2011 at 01:43 AM.
 
1 members found this post helpful.
Old 07-29-2011, 03:29 AM   #3
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by sag47 View Post
I'm no awk expert but I don't believe you can simply pipe the output of a command like that from within awk. To execute commands you have to use the system function for example system("date").
It might depend on the version of awk. It is part of at least the current GNU awk as described here.
 
Old 07-29-2011, 03:40 AM   #4
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by Lagos View Post
why wouldn't the following work?

Code:
awk 'BEGIN{FS="\n"; RS="++++++++++"; "date +F%"|getline dateVal} /dateVal/ {print $0}' log_file >/tmp/alert
/dateVal/ looks for exactly that, without substituting the value of dateVal. If you want to use a variable value as a regular expression then awk's dynamic regexp provisions apply. The code would be something like (not tested, spread over several lines and indented for legibility)
Code:
awk '
    BEGIN {
        FS = "\n";
        RS = "++++++++++";
        "date +F%" | getline dateVal
    }

    $0 ~ dateVal { print $0 }
' \
log_file >/tmp/alert
 
1 members found this post helpful.
Old 07-29-2011, 08:55 AM   #5
Lagos
LQ Newbie
 
Registered: Jun 2010
Location: Las Cruces, NM
Distribution: MAC OSX 10.6.4 / Fedora 12
Posts: 11

Original Poster
Rep: Reputation: 8
Thank you everyone for your timely replies. I really appreciate it.
 
Old 07-29-2011, 09:27 AM   #6
Lagos
LQ Newbie
 
Registered: Jun 2010
Location: Las Cruces, NM
Distribution: MAC OSX 10.6.4 / Fedora 12
Posts: 11

Original Poster
Rep: Reputation: 8
Quote:
Originally Posted by sag47 View Post
First off ` /= '. A back tick (`) which is part of the tilde (~) key above the tab key is not a single quote ('). You are right in saying that single quotes change the meaning of a command where echo "$PATH" and echo '$PATH' give two different outputs.

I'm no awk expert but I don't believe you can simply pipe the output of a command like that from within awk. To execute commands you have to use the system function for example system("date"). As for the rest I'll defer someone else who would know better.

By the way in your awk command the $i is not enclosed by single quotes. It is outside of them. Below I have highlighted the quoted text.

awk 'BEGIN{FS="\n"; RS="++++++++++"} /'$i'/ {print $0}' log_file >/tmp/alert

You might be able to do something like this.
Code:
#!/bin/bash
awk 'BEGIN{FS="\n"; RS="++++++++++"} /'`date +%F`'/ {print $0}' log_file >/tmp/alert
mail -s "mydata" root@localhost < /tmp/alert
or even better since there's no tmp file
Code:
awk 'BEGIN{FS="\n"; RS="++++++++++"} /'`date +%F`'/ {print $0}' log_file | mail -s "mydata" root@localhost
cool. this works. so, looking at the color coding above `date +%F` is outside the quotes as well. if this is the case, how do we get away with the syntax? shouldn't awk just choke?
 
Old 07-29-2011, 09:29 AM   #7
Lagos
LQ Newbie
 
Registered: Jun 2010
Location: Las Cruces, NM
Distribution: MAC OSX 10.6.4 / Fedora 12
Posts: 11

Original Poster
Rep: Reputation: 8
Quote:
Originally Posted by catkin View Post
/dateVal/ looks for exactly that, without substituting the value of dateVal. If you want to use a variable value as a regular expression then awk's dynamic regexp provisions apply. The code would be something like (not tested, spread over several lines and indented for legibility)
Code:
awk '
    BEGIN {
        FS = "\n";
        RS = "++++++++++";
        "date +F%" | getline dateVal
    }

    $0 ~ dateVal { print $0 }
' \
log_file >/tmp/alert
..this seems to be the most legible in terms of readability ***and** logic. thank you.
 
Old 07-29-2011, 09:58 AM   #8
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by Lagos View Post
cool. this works. so, looking at the color coding above `date +%F` is outside the quotes as well. if this is the case, how do we get away with the syntax? shouldn't awk just choke?
bash substitutes the output of date +%F for `date +%F` before awk sees it. So, for example, awk sees (using colour to identify individual "words" as given to awk)
Code:
awk BEGIN{FS="\n"; RS="++++++++++"} /2011-07-29/ {print $0} log_file
EDIT: BTW, you may prefer to use $( ... ) instead of ` ... `. It is functionally superior in complex cases but more importantly it is obviously not a single quoted string which the ` .. ` form can be mistaken for.

Last edited by catkin; 07-29-2011 at 10:00 AM.
 
1 members found this post helpful.
Old 07-29-2011, 10:10 AM   #9
Lagos
LQ Newbie
 
Registered: Jun 2010
Location: Las Cruces, NM
Distribution: MAC OSX 10.6.4 / Fedora 12
Posts: 11

Original Poster
Rep: Reputation: 8
Quote:
Originally Posted by catkin View Post
bash substitutes the output of date +%F for `date +%F` before awk sees it. So, for example, awk sees (using colour to identify individual "words" as given to awk)
Code:
awk BEGIN{FS="\n"; RS="++++++++++"} /2011-07-29/ {print $0} log_file
EDIT: BTW, you may prefer to use $( ... ) instead of ` ... `. It is functionally superior in complex cases but more importantly it is obviously not a single quoted string which the ` .. ` form can be mistaken for.
excellent....I'm one step closer to understanding the order of operations for shell expansion ...thx
 
Old 07-29-2011, 10:31 AM   #10
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by Lagos View Post
excellent....I'm one step closer to understanding the order of operations for shell expansion ...thx
Yes -- it helps de-mystify the shell. More info on it here.
 
1 members found this post helpful.
  


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 On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Variable and shell expansion timbCFCA Linux - Server 2 07-15-2011 01:21 PM
[SOLVED] awk: how can I assign value to a shell variable inside awk? quanba Programming 6 03-23-2010 02:18 AM
shell command using awk fields inside awk one71 Programming 6 06-26-2008 04:11 PM
Avoiding Shell Script Brace Expansion Woodsman Slackware 4 05-31-2008 09:36 AM
bash shell command line expansion hansi umayangan Linux - General 2 03-13-2005 11:31 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 11:44 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