bug-bash
[Top][All Lists]
Advanced

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

Re: Backslash mysteriously disappears in command expansion when unescapi


From: Charles-Henri Gros
Subject: Re: Backslash mysteriously disappears in command expansion when unescaping would reference an existing file
Date: Wed, 22 May 2019 22:23:04 +0000

On 5/22/19 3:13 PM, Robert Elz wrote:
>     Date:        Wed, 22 May 2019 17:34:22 +0000
>     From:        Charles-Henri Gros <address@hidden>
>     Message-ID:  <address@hidden>
>
>   | The problem I'm trying to solve is to iterate over regex-escaped file
>   | names obtained from a "find" command. I don't know how to make this
>   | work. It works with other versions of bash and with other shells.
>
> You were relying upon a common bug, which has been fixed in bash, but
> your technique is all wrong, you don't need any kind of loop at all, not
> a for loop, and not the while read loop that Greg suggested.
>
> find -print produces a list of names, one per line.   Those are simple
> strings, which fgrep (or grep -F as Andreas suggested) can handle finding.
>
> What I'd do is
>
>       fgrep "$(find .... -print)" wherever

Interesting, I didn't realize you could pass newline-separated patterns
to "grep" on the command line. Good to know for the future.

But unfortunately, grep was just illustrative, I'm using another tool
that takes a regex but has no "-F" option (though admittedly with some
effort I could add one, I wrote the tool in question).


>
> (You can use grep -F if you have an aversion to using its traditional name,
> but fgrep was once a different program to grep / egrep).
>
> This version will have a problem with filenames with embedded newlines,
> but so did your original, so I am simply assuming that you have none of
> those (using any variant of grep to search for strings containing newlines
> tends to be "difficult" as grep is a line at a time tool).
Yes I'm not expecting any special characters except "$".
>
> If you version of grep cannot handle the pattern list not having a
> terminating \n (the $() removes it) then you can add it back
>
>       fgrep "$(find ... -print)"$'\n' wherever.
>
> You're probably still going to need a | into sed inside the command
> substitution, as I doubt that you actually want to look for filenames
> in the format that find prints them (you have never shown your actual
> command) and I suspect that you want to delete the pathname component
> (a leading "./" or whatever) and it isn't clear what you want to
> happen with filenames in subdirectories.  But none of those manipulations
> will affect anything.
>
> The other difference between this method and the one that you were
> using, is that this one will mix up the output for all of the different
> file names (it reads the target files just once, looking for all of the
> filenames simultaneously) whereas your original scheme looked for each
> file name in the target sequentially (re-reading the target file(s) over
> and over again for each new file name).   That would group output lines
> for each file name together, whereas the technique above does not.

-- 
Charles-Henri Gros




reply via email to

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