[Top][All Lists]

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

Re: Backslash mysteriously disappears in command expansion when unescapi

From: Greg Wooledge
Subject: Re: Backslash mysteriously disappears in command expansion when unescaping would reference an existing file
Date: Wed, 22 May 2019 15:28:04 -0400
User-agent: Mutt/1.10.1 (2018-07-13)

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

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:

while IFS= read -rd '' file; do
  args+=(-e "$file")
done < <(find ... -print0)
grep -F "address@hidden" /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.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]