On Wed, May 22, 2019 at 07:14:44PM +0000, Charles-Henri Gros wrote: > The file name is the regex (argument to "-e"), not the file "grep" > reads. I want to check that some text file contains a reference to a file. > > But it looks like this would work: > > for file in $(find ...); do grep -e "$(echo -n "$file" | sed 's/\$/\\$/g')" > someinput; done
That still has the same problems. I've already given the BashPitfalls link so I won't repeat that whole speech. Since it seems you want to repeat your search for every file name individually, the while read loop becomes a viable choice. find ... -print0 | while IFS= read -rd '' file; do grep -F -e "$file" /some/textfile done This is still going to be inefficient compared to running *one* grep with all of the input filenames as matchable patterns, but if you're set on doing it the slow way, so be it. The faster way can be done safely as long as there aren't *too* many filenames to pass: args=() while IFS= read -rd '' file; do args+=(-e "$file") done < <(find ... -print0) grep -F "${args[@]}" /some/textfile That will fail if there are too many arguments. A less-safe but still fast way would involve generating a newline-delimited list of the matchable filename-patterns, which means it'll fail if any filenames have newlines in them. Ignoring that for now, we get: grep -F -f <(find ... -print) /some/textfile You can add something like ! -name $'*\n*' to the find arguments to prevent such filenames from being handled. (Actually, the whole thing fails pretty catastrophically if any of your filename-patterns have newlines in them, since grep can't handle patterns with newlines... so you'd want to filter those out even in the array-based alternative.) In any case, for f in $(find...) is always wrong. Sorry, but it's true. There's no salvaging it.