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