experchange > shell

Charlie Roberts (01-13-20, 09:03 PM)
Any help wiith this probelem would be appreciated.

I need to print out a couple of lines for files that match a given
string. The files all resied in one directory. The lines I need
contain an ID string and so I can use grep once I have a
filename. I would also like to print out the filename. This
last part is where I have a problem

Let the filenames I am interested in contain the string 'xyz'
What I do now is use the function

getinfo () {
grep Date /cygdrive/k/WDmrk4/toc/F04/Data/*$1*
grep Source /cygdrive/k/WDmrk4/toc/F04/Data/*$1*
}

and invoke it with getinfo xyz

This works ... it prints out the lines containing the strings
'Date' and 'Source' in all the files that match.

However, I would also like the output to have the filename
printed out before the lines I am looking for.

I tried a simple for loop and it fails. At its simplest

getid2 () {
for file in*$1*; do
echo $file
done
}

simply prints out *xyx*.

It looks like I have to create an array fo the matched
filenames first, but what I find of the web is not helping.

Any suggestions will be greatly appreciated.

thanks.
Tobiah (01-13-20, 09:10 PM)
On 1/13/20 11:03 AM, Charlie Roberts wrote:
> I would also like to print out the filename. This
> last part is where I have a problem


If I understand what you're after, my grep has
a -H flag which forces the filename when only
one file is searched. Maybe you can parse
that out.
Benjamin Esham (01-13-20, 09:41 PM)
Charlie Roberts wrote:

> However, I would also like the output to have the filename
> printed out before the lines I am looking for.


As another poster mentioned, adding the "-H" flag to your grep invocations
might be all you need.

[..]
> done
> }
> simply prints out *xyx*.


The problem is that there are no files matching the glob pattern *xyz*. In
your original example you are looking for files in
/cygdrive/k/WDmrk4/toc/F04/Data, but in getid2 you are looking for files in
whatever the current directory happens to be. Did you mean to write

for file in /cygdrive/k/WDmrk4/toc/F04/Data/*$1*; do

here too?

The reason you're seeing "*xyx*" printed out is that the default behavior of
bash (among other shells) is that a glob pattern that doesn't match anything
is left as-is. In your case, that means a string with literal asterisks in
it. (This is kind of a silly design; you can read more about the rationale
for it in [1].) If you're using bash, you could add the line

shopt -s nullglob

somewhere at the top of your script. This has the effect of turning a
failing glob into an empty string. In other words, if the glob pattern
doesn't match any files then the body of the for loop will never be
executed. (To be clear, though, I don't think your underlying problem is
this globbing behavior; I think it's that your glob needs to specify a
directory to be searched.)

Hope this helps,

Benjamin

[1]
Janis Papanagnou (01-13-20, 10:14 PM)
On 13.01.2020 20:03, Charlie Roberts wrote:
[..]
> 'Date' and 'Source' in all the files that match.
> However, I would also like the output to have the filename
> printed out before the lines I am looking for.


You already got answers, so I mention just two potential options for
the code above.

You don't need two grep calls if you just want to find two patterns
(unless you want them in the given order), you can use an extended
regexp

grep -E 'Date|Source' /cygdrive/k/WDmrk4/toc/F04/Data/*$1*

which is in this case better than duplicating the filename.

To get the filename - mind that option -H is non-standard - there's
also the option to add /dev/null as pseudo file to your call

grep -E 'Date|Source' /dev/null /cygdrive/k/WDmrk4/toc/F04/Data/*$1*

But if there's no matching file you will still get an error, of course.

Janis
[..]
Charlie Roberts (01-13-20, 10:20 PM)
On Mon, 13 Jan 2020 14:03:24 -0500, Charlie Roberts
<croberts> wrote:

[..]
>filenames first, but what I find of the web is not helping.
>Any suggestions will be greatly appreciated.
>thanks.


Problem solved! Did a bit of reading ....
met (01-13-20, 10:38 PM)
>I need to print out a couple of lines for files that match a given
[..]
>simply prints out *xyx*.
>It looks like I have to create an array fo the matched
>filenames first, but what I find of the web is not helping.


No array needed, think you just need to add a test to be
sure the directory containing the files exists then run
the function. This test seems to work okay:

$ cat ./foo/*
Date Mon Jan 13 13:10:39 MST 2020
Source /tmp/foo/file1
Date Mon Jan 13 13:10:39 MST 2020
Source /tmp/foo/file2
Date Mon Jan 13 13:10:39 MST 2020
Source /tmp/foo/file3
Charlie Roberts (01-21-20, 09:27 PM)
On Mon, 13 Jan 2020 11:41:59 -0800, Benjamin Esham <usenet>
wrote:

[..]
>Hope this helps,
>Benjamin
>[1]


Thanks to all who responded.

You are correct! In my hurry, I did forget to specify the
proper path. Dumb!!

I did get a script with an anrray construct to work though I like
all of the suggestions. I have modified the script to make it
leaner.
Similar Threads