0

There is a my_grep script

#!/bin/csh
cat $1 | grep -i -E " a | b "

How come

cat a* | grep -i -E " a | b " > out1.txt

and

my_grep a* > out2.txt

yield different results?

Evgeny
  • 2,121
  • 1
  • 20
  • 31

3 Answers3

1

a* will expand in shell before going to shell script. Thus, my_grep a* will give only the first file starting with a to be processed by your script. On the other hand, cat a* will work on all the files starting with a*. You can change the script to cat $* and that will achieve the desired result.

unxnut
  • 8,509
  • 3
  • 27
  • 41
  • `$*` is almost never the optimal solution for this problem. Use `"$@"` in sh-like shells (bash, ksh, dash, sh), and `$*:q` in csh-like shells (tcsh, csh) instead. – Uwe May 23 '13 at 11:59
1

That would be because $1 is the first argument rather than all of them.

The shell will expand the wildcard into individual files before your script sees it.

So, if you have the following two files a1 and a2, the command my_grep a* will give you the two files into $1 and $2 and your script will only process the first.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
1

Quick solution:

They differ because you are only cating the FIRST glob expansion $1 in my_grep script ... Your my_grep should be:

#!/bin/csh

cat $* | grep -i -E " a | b "

the $* are all the command-line arguments passed to my_grep.

Some detail

The command-line shell (where you are actually typing my_grep a* is expanding the a* to all the filenames that begin with a so let's say you had afoo abar and abaz in you directory, then:

cat a* | grep -i -E " a | b "

is essentially equivalent to:

cat abar abaz afoo | grep -i -E " a | b "

similarly when you do my_grep a*

it's equivalent to

my_grep abar abaz afoo

so in you shell script cat $1 means JUST cat abar and NOT cat abar abaz afoo

$* is equivalent of $argv (which is equivalent of $argv[*]).

so your my_grep should be as shown above.

Ahmed Masud
  • 21,655
  • 3
  • 33
  • 58