[comp.unix.questions] Awk with passed parameters

nfs1675@dsacg3.dsac.dla.mil ( Michael S Figg) (03/08/91)

I'm trying to write a short shell script using awk to list files in the
current directory that have todays' date on them. It seems like something
like this should work, but I haven't had any luck:

set d = `date`
ls -l | awk '$5 == x && $6 == y  {print}' x=$d[2] y=$d[3]

This in a C shell on a BSD machine where $5 is the month and $6 is the day.
I've also tried this on a SVR3.2 machine with a Bourne shell and get similar
results, usually that it can't open "Mar", which I'm assuming is coming from
the 'x=$d[2]'. Any clues on what I'm doing wrong?  I'm sure there are other
ways to do this, but I'd like to get more familar with awk.

---Mike

-- 
 --------       o       A herd of bagels      | Michael Figg  DSAC-FSD
 |      |  --  oo o o   escaping from a deli. | DLA Systems Automation Center
 |      |  -- ooo oo    Looking for Lox in    | Cols, Ohio mfigg@dsac.dla.mil
 --------      o o      all the wrong places  | CIS: 73777,360    

tchrist@convex.COM (Tom Christiansen) (03/08/91)

From the keyboard of nfs1675@dsacg3.dsac.dla.mil ( Michael S Figg):
:I'm trying to write a short shell script using awk to list files in the
:current directory that have todays' date on them. It seems like something
:like this should work, but I haven't had any luck:
:
:set d = `date`
:ls -l | awk '$5 == x && $6 == y  {print}' x=$d[2] y=$d[3]
:
:This in a C shell on a BSD machine where $5 is the month and $6 is the day.
:I've also tried this on a SVR3.2 machine with a Bourne shell and get similar
:results, usually that it can't open "Mar", which I'm assuming is coming from
:the 'x=$d[2]'. Any clues on what I'm doing wrong?  I'm sure there are other
:ways to do this, but I'd like to get more familiar with awk.

The first thing is that you need to put your variable assignments
in front of your program.  You probably should protect your string
literals with double quotes so it doesn't think they are variables.

#!/bin/csh -f
set d = `date`
ls -l | awk x='"'$d[2]'"' y='"'$d[3]'"' '$5 == x && $6 == y  {print}' 

(Isn't quoting *fun* in the csh?)

However, to my dismay I found that this is entirely rejected by
the standard awk distributed with most systems.  Nawk was able
to handle the first assignment, but got all confused by the time
we hit the second one.  Only gawk did the right thing with this code.

What you could do then is just embed the assignments in a BEGIN block:

#!/bin/csh -f
set d = `date`
ls -l | awk 'BEGIN { x = "'"$d[2]"'"; y = "'"$d[3]"'"} $5 == x && $6 == y  {print}' 

This will work on all three versions of awk.

You might consider using the real shell for your scripts.  It will pay
off again and again.

#!/bin/sh
set `date`
ls -l | awk "BEGIN { x = \"$2\"; y = \"$3\"} \$5 == x && \$6 == y  {print}"

quoting is certainly easier, and there are other very good reasons as well.

On the other hand, after seeing what a pain this is, you might begin
to understand why I so often just throw out the whole shebang and
write it in perl instead.

--tom

art@pilikia.pegasus.com (Art Neilson) (03/10/91)

In article <3022@dsacg3.dsac.dla.mil> nfs1675@dsacg3.dsac.dla.mil ( Michael S Figg) writes:
>
>
>I'm trying to write a short shell script using awk to list files in the
>current directory that have todays' date on them. It seems like something
>like this should work, but I haven't had any luck:
>
>set d = `date`
>ls -l | awk '$5 == x && $6 == y  {print}' x=$d[2] y=$d[3]

Here's my solution using the Bourne shell and standard awk.

:

date="`date`"
set $date

ls -l | awk '
BEGIN {
	mm = '\"$2\"'
	dd = '\"$3\"' + 0
}
	$6 == mm && $7 == dd { print }
'
-- 
Arthur W. Neilson III		| INET: art@pilikia.pegasus.com
Bank of Hawaii Tech Support	| UUCP: uunet!ucsd!nosc!pilikia!art

jik@athena.mit.edu (Jonathan I. Kamens) (03/11/91)

In article <1991Mar08.141340.26881@convex.com>, tchrist@convex.COM (Tom Christiansen) writes:
|> The first thing is that you need to put your variable assignments
|> in front of your program.  You probably should protect your string
|> literals with double quotes so it doesn't think they are variables.

  This is not true.  Awk reads variable assignments in "file arguments" and
does the assignments *before* the main body of the awk program is executed. 
The only problem with the program as originally posted was that he needed to
add "-" to the end of the awk command to tell it to read from stdin after
reading the other "file arguments" (which were actually variable assignments).

  If he adds that dash, then things should work on virtually any version of
awk, since variable assignments in file arguments were supported in very early
versions of awk and have continued to be supported in most versions.  Tom, do
you know of a version of awk which won't work properly if an extra file
argument of "-" is added to the end of the awk command?

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710

tchrist@convex.COM (Tom Christiansen) (03/11/91)

From the keyboard of jik@athena.mit.edu (Jonathan I. Kamens):
:  If he adds that dash, then things should work on virtually any version of
:awk, since variable assignments in file arguments were supported in very early
:versions of awk and have continued to be supported in most versions.  Tom, do
:you know of a version of awk which won't work properly if an extra file
:argument of "-" is added to the end of the awk command?

Nope, that seems to work on on the version I just tested.

It really bugs me though that you should have to do that for old awk
and not for the more recent incarnations.  I call it a bug.

--tom

peter@doe.utoronto.ca (Peter Mielke) (03/12/91)

In <1991Mar10.033553.28978@pilikia.pegasus.com>, Art Neilson writes:
> In article <3022@dsacg3.dsac.dla.mil> ( Michael S Figg) writes:
> >I'm trying to write a short shell script using awk to list files in the
> >current directory that have todays' date on them. It seems like something
> >like this should work, but I haven't had any luck:
>
> Here's my solution using the Bourne shell and standard awk.
> 
> :
> 
> date="`date`"
> set $date
> 
> ls -l | awk '
> BEGIN {
> 	mm = '\"$2\"'

This should be written like this, as it will fail if $2="two or more words"

 	mm = "'"$2"'"

> 	dd = '\"$3\"' + 0

 	dd = '"$3"' + 0

> }
> 	$6 == mm && $7 == dd { print }
> '
> -- 
> Arthur W. Neilson III		| INET: art@pilikia.pegasus.com
> Bank of Hawaii Tech Support	| UUCP: uunet!ucsd!nosc!pilikia!art
-- 
Peter Mielke                                    peter@doe.utoronto.ca
Dictionary of Old English Project               utgpu!utzoo!utdoe!peter
University of Toronto

art@pilikia.pegasus.com (Art Neilson) (03/12/91)

In article <1991Mar10.235414.28125@athena.mit.edu> jik@athena.mit.edu (Jonathan I. Kamens) writes:
>In article <1991Mar08.141340.26881@convex.com>, tchrist@convex.COM (Tom Christiansen) writes:
>|> The first thing is that you need to put your variable assignments
>|> in front of your program.  You probably should protect your string
>|> literals with double quotes so it doesn't think they are variables.
>
>  This is not true.  Awk reads variable assignments in "file arguments" and
>does the assignments *before* the main body of the awk program is executed. 
>The only problem with the program as originally posted was that he needed to
>add "-" to the end of the awk command to tell it to read from stdin after
>reading the other "file arguments" (which were actually variable assignments).
>
>  If he adds that dash, then things should work on virtually any version of
>awk, since variable assignments in file arguments were supported in very early
>versions of awk and have continued to be supported in most versions.  Tom, do
>you know of a version of awk which won't work properly if an extra file
>argument of "-" is added to the end of the awk command?

Hey! use of that dash is a nifty trick.  I have always done shell quoting
tricks to pass shell parameters to old awk, the dash technique is a much
better method.  The following works fine on my system, although I need a
+ 0 on the day passed from the date command output in order to make it
compare correctly with the day field in the ls command output (for days
of the month between 1 and 9).  This works for me:

set `date`
ls -l | awk '$6 == mm && $7 == dd + 0 { print }' mm=$2 dd=$3 -
-- 
Arthur W. Neilson III		| INET: art@pilikia.pegasus.com
Bank of Hawaii Tech Support	| UUCP: uunet!ucsd!nosc!pilikia!art

lugnut@sequent.UUCP (Don Bolton) (03/15/91)

In article <1991Mar10.033553.28978@pilikia.pegasus.com> art@pilikia.pegasus.com (Art Neilson) writes:
>In article <3022@dsacg3.dsac.dla.mil> nfs1675@dsacg3.dsac.dla.mil ( Michael S Figg) writes:
>>
>>
>>I'm trying to write a short shell script using awk to list files in the
>>current directory that have todays' date on them. It seems like something
>>like this should work, but I haven't had any luck:
>>
>>set d = `date`
>>ls -l | awk '$5 == x && $6 == y  {print}' x=$d[2] y=$d[3]
>
>Here's my solution using the Bourne shell and standard awk.
>
>:
>
>date="`date`"
>set $date
>
>ls -l | awk '
>BEGIN {
>	mm = '\"$2\"'
>	dd = '\"$3\"' + 0
>}
>	$6 == mm && $7 == dd { print }
>'

I may be missing something obvious here but why use awk at all?

IFS=': '
set `date`
hrs=$4
m=$2   

etc

works just fine for a 12 hour clock display I use from the date output


Don "1600 hrs reminds me of people with bad haircuts and boots" Bolton

jik@athena.mit.edu (Jonathan I. Kamens) (03/16/91)

In article <55345@sequent.UUCP>, lugnut@sequent.UUCP (Don Bolton) writes:
|> I may be missing something obvious here but why use awk at all?
|> 
|> IFS=': '
|> set `date`
|> hrs=$4
|> m=$2   
|> 
|> etc
|> 
|> works just fine for a 12 hour clock display I use from the date output

  How does this solve the problem that the original poster is trying to solve?

  He wanted to use awk to filter the output of "ls" to print out only those
files that were modified today.  What you posted above explains how to set the
month and day to shell variables.  But how are you going to then use that to
filter the output of ls?  If you try to do it completely in the shell, you're
going to have to pipe the output of ls into a loop or function that matches
each line against the month and day.  The matching will have to be done using
"test" or "expr".  Which means (unless you've got a shell with "test" built
in) that you're going to be forking a process to do the test for every line in
the ls listing.

  Is that really what you intended to suggest, or am I missing something?

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710

lugnut@sequent.UUCP (Don Bolton) (03/22/91)

In article <1991Mar15.182242.18780@athena.mit.edu> jik@athena.mit.edu (Jonathan I. Kamens) writes:
>In article <55345@sequent.UUCP>, lugnut@sequent.UUCP (Don Bolton) writes:
>|> I may be missing something obvious here but why use awk at all?
>|> 
>|> IFS=': '
>|> set `date`
>|> hrs=$4
>|> m=$2   
>|> 
>|> etc
>|> 
>|> works just fine for a 12 hour clock display I use from the date output
>
>  How does this solve the problem that the original poster is trying to solve?
>
>  He wanted to use awk to filter the output of "ls" to print out only those
>files that were modified today.  What you posted above explains how to set the
>month and day to shell variables.  But how are you going to then use that to
>filter the output of ls?  If you try to do it completely in the shell, you're
>going to have to pipe the output of ls into a loop or function that matches
>each line against the month and day.  The matching will have to be done using
>"test" or "expr".  Which means (unless you've got a shell with "test" built
>in) that you're going to be forking a process to do the test for every line in
>the ls listing.
>
>  Is that really what you intended to suggest, or am I missing something?
>
Pretty much was what I were suggesting.

I tend to use awk/nawk for gobs of things, but I've also done a lot of
date "functions" just using simple shell.

and to be true, I was a tad unclear as to what his real mission was.

Don "hmm Asics don't taste too bad, little rubbery though" Bolton