bourne shell query

bourne shell query

Post by Jukka Partan » Fri, 31 Aug 1990 21:17:36




Quote:>files=`ls -rt * |grep -v '.*[a-zA-Z].*' | awk $1 '>=' $zots {print}`

files=`ls -rt | grep -v '.*[a-zA-Z].*' | awk '$1 >= '$zots' {print}`

--

          A mountain is something you don't wanna * with.

 
 
 

bourne shell query

Post by Jukka Partan » Fri, 31 Aug 1990 21:19:09


        Argh, forgot one '

Quote:>files=`ls -rt | grep -v '.*[a-zA-Z].*' | awk '$1 >= '$zots' {print}`

files=`ls -rt | grep -v '.*[a-zA-Z].*' | awk '$1 >= '$zots' {print}'`
--

          A mountain is something you don't wanna * with.

 
 
 

bourne shell query

Post by Fred Whitesi » Fri, 31 Aug 1990 09:56:38


        i have a simple little shell question.  I am attempting
to write a script that will perform various manipulations on news
articles.  my problem seems to be with understanding variable
substitution in sh.  a minimal example is the enclosed sh script.  what
it should do is set the variable files to be the names of those
articles in comp.std.c whose name (article number) is greater than or
equal to the numeric value of the scripts first argument.  this does
not behave as expected.  i have tried quite a unmber of variations on
this theme (mostly centering around multiple $'s and interesting
quoting of commands, but i tend to get all of the files or none of them
depending on (for some reason) the number of $'s preceding the zots
variable name (also on  the number in front of the 1, $1 or $$1, etc.
but i expected that ...) this is running under sunos4.1 if that is
interesting.  i have tried to read the manual, but with little
success.  anyone interested in pointing out my clear stupidity
publicly?  i *would* appreciate it ....

        many thanks ...

#!/bin/sh
cd /usr/spool/news/comp/std/c
zots=$1
echo "Should ignore files with name < $zots"
files=`ls -rt * |grep -v '.*[a-zA-Z].*' | awk $1 '>=' $zots {print}`
echo $files

--
Fred Whiteside   Chedoke-McMaster Hospitals, Hamilton, Ontario, Canada


 
 
 

bourne shell query

Post by Jeff Beadl » Fri, 31 Aug 1990 23:55:44


:>
:>   i have a simple little shell question.  I am attempting
:>to write a script that will perform various manipulations on news
:>articles.  my problem seems to be with understanding variable
:>substitution in sh.  a minimal example is the enclosed sh script.  what
:>it should do is set the variable files to be the names of those
:>articles in comp.std.c whose name (article number) is greater than or
:>equal to the numeric value of the scripts first argument.  this does
:>not behave as expected.  i have tried quite a unmber of variations on
:>this theme (mostly centering around multiple $'s and interesting
:>quoting of commands, but i tend to get all of the files or none of them
:>depending on (for some reason) the number of $'s preceding the zots
:>variable name (also on  the number in front of the 1, $1 or $$1, etc.
:>but i expected that ...) this is running under sunos4.1 if that is
:>interesting.  i have tried to read the manual, but with little
:>success.  anyone interested in pointing out my clear stupidity
:>publicly?  i *would* appreciate it ....
:>
:>   many thanks ...
:>
:>#!/bin/sh
:>cd /usr/spool/news/comp/std/c
:>zots=$1
:>echo "Should ignore files with name < $zots"
:>files=`ls -rt * |grep -v '.*[a-zA-Z].*' | awk $1 '>=' $zots {print}`
              I see a quoting problem here     ^^^^^^^^^^^^^^^^^^^^^
:>echo $files
:>
:>--
:>Fred Whiteside   Chedoke-McMaster Hospitals, Hamilton, Ontario, Canada


Quote:>files=`ls -rt * |grep -v '.*[a-zA-Z].*' | awk $1 '>=' $zots {print}`

This line is the problem, replace it with:

files=`ls -rt * |grep -v '.*[a-zA-Z].*' | awk "\$1 >= $zots {print}"`

Or, to make it a little more simpler... (You don't need .*'s in the grep)

files=`ls -rt * |grep -v '[a-zA-Z]' | awk "\$1 >= $zots {print}"`

To explain:

The only real change was to change thw quoting around the awk script.
$1 was getting expanded to the shell's $1, not the 1st awk field.

By using " as a quoting character, the shell is able to expand $zot to whatever
number it represents.  The \$1 is to prevent the shell from trying to expand $1
to the shell's $1, rather than the 1st awk field.

After the shell is finished with variable substitution,

awk "\$1 >= $zots {print}"

is transformed, and awk see's:  (if zot = 10)

awk "$1 >= 10 {print}"

Hope this helps!  A decent book on shell programming and quoting is the Howard
Sam's book on shell programming.

        -Jeff
--

Utek Engineering, Tektronix Inc.        +1 503 685 2568
                        SPEEA - Just say no.

 
 
 

bourne shell query

Post by James Brist » Sat, 01 Sep 1990 01:59:33


On 30 Aug 90 00:56:38 GMT,

Quote:> #!/bin/sh
> cd /usr/spool/news/comp/std/c
> zots=$1
> echo "Should ignore files with name < $zots"
> files=`ls -rt * |grep -v '.*[a-zA-Z].*' | awk $1 '>=' $zots {print}`
> echo $files

I changed the next to last line to this:
files=`ls -rt * |grep -v '.*[a-zA-Z].*' | awk '$1 >= '$zots' {print}'`

Awk expects its program to be one argument. You've given it four. You DON'T
want the $1 to be expanded, but you DO want the $zots to be expanded, hence
the funny quoting.

James
--

DEC Western Software Lab., Palo Alto, California.         .....!decwrl!brister

 
 
 

bourne shell query

Post by Jeff Beadl » Sat, 01 Sep 1990 05:34:55



>As a side question, does ANYONE have any bourne shell routines which do
>math... reasonably effeciently?  (For numbers > 1000?)

Well, I use expr.  For example:

a=123456
b=123

c=`expr $a - $b`

d=`expr $a \* $b`

echo "c = $c"
echo "d = $d"

Note, that the '*' MUST be quoted, as the shell will expand it.

"Shell qouting --  Know it, live it, be it.  -Jeff"    :-)

        -Jeff
--

Utek Engineering, Tektronix Inc.        +1 503 685 2568
                        SPEEA - Just say no.

 
 
 

bourne shell query

Post by Scott Yeli » Sat, 01 Sep 1990 01:49:30


Quote:>:>files=`ls -rt * |grep -v '.*[a-zA-Z].*' | awk $1 '>=' $zots {print}`
>I see a quoting problem here     ^^^^^^^^^^^^^^^^^^^^^
>files=`ls -rt * |grep -v '[a-zA-Z]' | awk "\$1 >= $zots {print}"`
>To explain:
> The only real change was to change thw quoting around the awk script.
>$1 was getting expanded to the shell's $1, not the 1st awk field.
>   By using " as a quoting character, the shell is able to expand $zot
>to whatever number it represents.  The \$1 is to prevent the shell
>from trying to expand $1 to the shell's $1, rather than the 1st awk
>field.

I still see a quoting problem here...
At least, when I try this-- it doesn't work.

I have only been able to get awk to work properly if I use
single quotes and not double quotes.

As a side question, does ANYONE have any bourne shell routines which do
math... reasonably effeciently?  (For numbers > 1000?)
--
Signature follows. [Skip now]

 -----------------------------------------------------------------------------

 After he pushed me off the cliff, he asked me, as I fell, ``Why'd you jump?''

 ODU/UNIX/BSD/X/C/ROOT/XANTH/CS/VSVN/
 -----------------------------------------------------------------------------

 
 
 

bourne shell query

Post by Dan Merc » Sun, 02 Sep 1990 04:25:34


:
:>As a side question, does ANYONE have any bourne shell routines which do
:>math... reasonably effeciently?  (For numbers > 1000?)
:
:Well, I use expr.  For example:
:
:a=123456
:b=123
:
:c=`expr $a - $b`
:
:d=`expr $a \* $b`
:
:echo "c = $c"
:echo "d = $d"
:
:Note, that the '*' MUST be quoted, as the shell will expand it.
:
:"Shell qouting --  Know it, live it, be it.  -Jeff"    :-)
:
:       -Jeff
:--

:Utek Engineering, Tektronix Inc.       +1 503 685 2568
:                       SPEEA - Just say no.

If your system has named pipes - fifos - and bc then you may find this
useful:

#
# these instructions illustrate how to set up a background
# engine in a shell script - a simple application is shown only
# for illustration purposes - it numbers lines of standard input

# first allocate fifos

ITMP=/usr/tmp/i.$LOGNAME
OTMP=/usr/tmp/o.$LOGNAME

/bin/rm -f $ITMP $OTMP 2>/dev/null
/etc/mknod $ITMP p  # input fifo for engine
/etc/mknod $OTMP p  # output fifo for engine

# start background engine and open $ITMP as file descriptor 3
# and $OTMP as file descriptor 4

bc <$ITMP >$OTMP &
exec 3>$ITMP
exec 4<$OTMP

# send command to background engine
# if background engine is bc,  counters can be maintained
# echo "x = 1"
# echo "x = x + 1" or echo "++x"
#the second version returns the new value of x

echo "x = 0" >&3

while line=`line`
        do
        echo "x++" >&3
        # read response
        read ans <&4
        echo "$ans: $line"
        done < engine

# terminate background engine and remove fifos

echo "quit" >&3
/bin/rm -f $ITMP $OTMP

exit 0
--

Dan Mercer

"MAN - the only one word oxymoron in the English Language"

 
 
 

bourne shell query

Post by Neil Smithli » Sun, 02 Sep 1990 04:28:56



>...

>#!/bin/sh
>cd /usr/spool/news/comp/std/c
>zots=$1
>echo "Should ignore files with name < $zots"
>files=`ls -rt * |grep -v '.*[a-zA-Z].*' | awk $1 '>=' $zots {print}`
>echo $files

The best way to figure this out is to go into the shell and start
typing.  To find the problem, run /bin/sh and go into the correct
directory.  Once there try the command
        ls -rt *
and see if this produces the correct output - if it does see what
happens if you add the grep.  If this works try the awk.  You'll see
that this causes awk to bail out.  Even if you reduce the awk
statement to
        awk $1 '>=' 1 {print}
awk still gives you an error message.  From this you can conclude that
this has nothing to do with the rest of the line and resort to the old
awk man page.  If you quote the arguments, all works fine.  That is:
        awk '$1 >= 1 {$print}'
works.  Now to add the shell variable $zots to this just insert it
*unqoted* into the line
        zots=1
        awk '$1 >= '$zots' {print}'
Once you have this just replace the awk statement in your program with
the above line and all works properly.

In general, I find that complex shell quoting is best solved with an
inside-out approach, get the inside to work and then add the next
level of quotes to that - of course, as you get better you need to
do less and less of this - Neil
--
========================================================================
Neil Smithline

UUCP:    ..!rutgers!rochester!smithln

 
 
 

bourne shell query

Post by Roger Rohrba » Sun, 02 Sep 1990 06:37:32



>cd /usr/spool/news/comp/std/c
>zots=$1
>echo "Should ignore files with name < $zots"
>files=`ls -rt * |grep -v '.*[a-zA-Z].*' | awk $1 '>=' $zots {print}`
>echo $files

There are two problems: first, awk expects its first argument to be a
an awk program; you are giving the program as 4 separate arguments
($1, '>=', $zots, {print}), so your program currently will cause awk
to bail out.  Second, you are not escaping the "$1" in your awk program,
so the shell is substituting the first parameter to your script there
(i.e., awk is seeing the number you gave as an argument, not "$1").
If you change the last part of your pipeline to

    awk '$1 >= '$zots' {print}'

it will work, because the "$1" is quoted for awk's sake, and all white
space is quoted to prevent the shell from passing 4 strings, not 1, to
awk as arguments.  Note that we step out of the quotes long enough to
let the shell substitute for "$zots".

ADVANCED DISCUSSION:

One might think you could use double quotes around the whole awk program,
and just escape the "$1" but not "$zots", thus:

    awk "\$1 >= $zots {print}"

and indeed this would work if it were not for the fact that the entire
pipeline is enclosed in backquotes.  A peculiarity of backquoting is
that it forces an extra level of evaluation, so "\$1" is no safer than
"$1".  You must use

    awk "\\$1 >= $zots {print}"

to get this to work.

Another subtlety: if your program were not doing a numeric comparison,
you'd have to arrange for "$zots" to be presented to awk as a string.
My first example would become something like

    awk '$1 == "'$zots'" {print}'

and the second,

    awk "\\$1 == \"$zots\" {print}"


- Eddie sez: ----------------------------------------------- (c) 1986, 1990 -.
|   {o >o                                                                     |
|    \ -) "I was an infinitely hot and dense dot."                            |

 
 
 

bourne shell query

Post by William R. Pring » Sun, 02 Sep 1990 12:11:32




>>cd /usr/spool/news/comp/std/c
>>zots=$1
>>echo "Should ignore files with name < $zots"
>>files=`ls -rt * |grep -v '.*[a-zA-Z].*' | awk $1 '>=' $zots {print}`
>>echo $files

(Followed by several variations on how to arrange quotes so that
a shell variable can get into an AWK program.)

I'm surprised no one mentioned the simple way:

        awk '$1 >= MAX{print}' MAX=$zots -

The MAX=value sets the awk variable MAX to 'value', the dash is needed
to indicate using stdin.  You could eliminate the grep by letting awk
do it for you:

        awk '/^[0-9]*/{if ($1 >= MAX) print}' MAX=$zots -

No that we have probably confused the original poster beyond hope ...

Good luck!
Bill Pringle

The nice thing about Unix is that there are so many right answers!

 
 
 

bourne shell query

Post by Matt D » Mon, 03 Sep 1990 08:44:10



>As a side question, does ANYONE have any bourne shell routines which do
>math... reasonably effeciently?  (For numbers > 1000?)

For the Bourne shell, the most efficient way to do math is to use the "expr"
program.  It doesn't support floating point, but it doesn't have any trouble
with numbers larger than 1000.  If you have a shell script that needs to do
a lot of math, I suggest you use the C shell built in math operators; it's
much faster (or perl, of course).
--

 
 
 

bourne shell query

Post by Jeffrey Gleixn » Mon, 03 Sep 1990 23:16:01





> >As a side question, does ANYONE have any bourne shell routines which do
> >math... reasonably effeciently?  (For numbers > 1000?)

> For the Bourne shell, the most efficient way to do math is to use the "expr"
> ...  If you have a shell script that needs to do
> a lot of math, I suggest you use the C shell built in math operators; it's

If you're going to do a lot of math write a {your favorite language besides
*sh here} program to do the math for you.  Even if you're doing a small
amount of math it will really speed it up.
i.e.
#!/bin/sh
count 1 6 | while read value ; do
        some commands...
done

=========
/*
 *      Count.c
 *
 *      print succesive numbers from start to end.
 *      Used in scripts instead of `expr $i +1`
 */
#include <stdio.h>
main(argc,argv)
int argc; char *argv[];
{
register int i,j;
i=atoi(argv[1]);
j=atoi(argv[2]);
while (i <= j)
        printf(" %d",i++);

Quote:}

--

 
 
 

bourne shell query

Post by Scott Yeli » Tue, 04 Sep 1990 03:14:26


Quote:>#include <stdio.h>
>int argc; char *argv[];
>while (i <= j)
> printf(" %d",i++);

Hmmm.. that's the STRANGEST sh program I have ever seen...
It must be that CSH that I keep hearing about!  :-)

This next routine isn't supposed to be sophisticated... but it works--
just give it two SMALL NUMBERS.

ADDITION ()
 {
  NUM1="$1"
  NUM2="$2"
  shift $#
  while test $# -lt $NUM1
  do

  done

  shift $#
  while test $# -lt $NUM2
  do

  done

  set - $NUM1 $NUM2
  TOTAL=$#
 }

I am working on a sort of LIBRARY of SHroutines where all I have to do is
include the clode  ``. COUNT'' for the next... and use the code.

COUNT ()
 {
  test $# = 0 &&\
   {
    echo "$0: Usage: $0 value [...]"
    exit 1
   } ||\
    {
     for i
      {
       set ""
       while :
       do
         set $* " x"
         echo $#
         if test $# = $i; then
           break
         fi
       done
     }
    }
 }

Of course, ``COUNT x'' is a great counter!  :-)

The main problem with the two loops is the ``set " $*"'' command.
This is what takes so much time when the argument list grows.

--
Signature follows. [Skip now]

 -----------------------------------------------------------------------------

 After he pushed me off the cliff, he asked me, as I fell, ``Why'd you jump?''

 ODU/UNIX/BSD/X/C/ROOT/XANTH/CS/VSVN/
 -----------------------------------------------------------------------------

 
 
 

1. And yet still another, that's right another, bourne shell query

'Twould be nice if people used subject lines with more content than the
word ``bourne'' (or perhaps ``csh'').

  Subject: Bourne: How to test if file descriptor 0 is open?

(Not that this plea will have any effect, but it was inevitable that
someone would make this post, so I decided to get it over with.)

---Dan

2. nslookup

3. Yet Another bourne shell query

4. hard and soft for multiple terminals computer?

5. Writing /dev/null to a file (Bourne shell query)

6. samba and windows networking

7. Light Speed Bourne Shell! (was: Bourne shell tricks)

8. configuring 2 HDDs within Boot Mgr...

9. Bourne shell {...} syntax query

10. Bourne Shell compatible shells (was: Request: which shells)

11. Changing from the Bourne shell to C-shell

12. Trying to run nohup from Korn shell but getting Bourne shell errors

13. Bourne Shell vs C-Shell