On Thu, Feb 27, 2020 at 05:13:18PM +0100, Albretch Mueller wrote: > On 2/27/20, Greg Wooledge <wool...@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.