[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: All true assertions in a bash find one liner? ...



On Thu, Feb 27, 2020 at 05:13:18PM +0100, Albretch Mueller wrote:
> On 2/27/20, Greg Wooledge <wooledg@eeg.ccf.org> wrote:
> > Do you want to search for all files in ~/java whose names end with
> > .java or .txt and which contain the string
> > "java.io.UnsupportedEncodingException;" ?
> 
>  Yes, I do!

Great!

>  But where is the  -printf '"%TD %TT",%Ts,%s,"%P"\n' part in your one liner?

Not great!

I guess I don't know what the goal is.

>  Include it:

Why?

>  find ~/java -type f \( -iname '*.java' -o -iname '*.txt' \) -printf
> '"%TD %TT",%Ts,%s,"%P"\n' -exec grep -l -F
> 'java.io.UnsupportedEncodingException;' {} +
> 
>  and you will see what I have been talking about

That prints some stuff for EVERY file whose name matches, regardless
of whether it contains the magic string.

The files which DO contain the magic string will also have their names
printed by grep.

I still don't know what you want, so let me just talk in the abstract
for a moment.

You've got two basic choices here:

(1) find hands filenames over to grep, and grep decides which filenames
    to print.
    
(2) find executes grep on a single-file-by-file basis, and uses the exit
    status of grep to determine whether to print stuff for that file.

In the hypothetical case where you want to print a bunch of crap about
each matching file BEYOND just the file's name, calling grep once
per file would certainly be ONE way to achieve your goal.  But it means
you're calling grep once for every single file, not in batch mode.
It would be pretty slow.  That may be an issue, or it may not.

Another way to achieve that hypothetical goal would be to start with
option 1, and perform a metadata lookup on each filename printed by
grep, to print additional crap.  Sort of like this:

find ... -exec grep -l ... {} + | file-metadata-looker-upper

Be aware that you can use grep -lZ to print NULs instead of newlines
after the matching filenames, if your file-metadata-looker-upper can
handle NUL delimiters.  You *should* do that, if at all possible, so
that your script handles filenames with newlines in them.

Or, you could be lazy, and tell find to ignore any filenames with
newlines in them with a ! -name $'*\n*' expression.

But... what's the actual goal?  Why do you want to print a bunch of
metadata about each file, beyond just its name?  Are you going to
sort it?  Are you going to filter it through another step?  Do you
just want to see it because you think it's pretty?

See, typically the goal is something like "... and then I want to
modify every one of those files", so you just want their names.

All that extra metadata crap just gets in the way and makes it harder
to do whatever the NEXT STEP is.  That's why I didn't consider it to
be an actual part of the problem specification.


Reply to: