help-bash
[Top][All Lists]
Advanced

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

Re: Can't find file


From: David Niklas
Subject: Re: Can't find file
Date: Fri, 15 Nov 2019 19:04:32 -0500

On Tue, 12 Nov 2019 09:30:31 -0500
Greg Wooledge <address@hidden> wrote:
> On Mon, Nov 11, 2019 at 08:24:58PM -0500, David Niklas wrote:
<snip>
> > When I invoke it on a file without spaces it works like a charm:
>
> https://mywiki.wooledge.org/Quotes
>
> OK, problem solv--
>
> > I can't quote the $(...) because I need to pass the --sub-file FILE as
> > separate arguments.
>
> GAAAHHHH.
>
> Does this awk command write SOMETHING OTHER THAN ONE FILE to stdout?
>
> What does it DO?
>
> If it attempts to write a LIST OF SHELL ARGUMENTS to standard output,
> then you need to take an ENTIRELY different approach to this problem.

Only one file per mpv command with multiple commands possible as each
mpv instance exits. mpv will only accept one subtitle file per
invocation so I have to do it this way.
If there are no subtitle files then I don't pass the --sub-file argument.
So 1 arg and 1 subtitle file.

> Let's speculate that "the awk command writes a series of shell
> arguments like --foo -b -a -r to stdout, and I want to use them as
> arguments in my mpv command".
>
> In THAT case, what you need to do is serialize this list of shell
> arguments in a way that bash can parse (deserialize) into an array.
> Then expand the array to generate the arguments of mpv.
>
> The easiest way to handle this would be to have the awk command
> write one argument (array element) per line, and then capture them
> in an array using newlines as delimiters:
>
> myfunc() {
>   local i args
>   for i; do
>     mapfile -t args < <(awk command from hell which writes one arg per
> line) mpv --static --arguments "${args[@]}"
>   done
> }
>
> This will fail if any of your arguments (filenames) contains a newline
> character, because the newline character will be seen as an array
> delimiter by mapfile.
>
> If that's a concern, then you'll need to use NUL delimiters instead of
> newline delimiters.  Or, you could simply disallow filenames that
> contain newline characters.
>
> Another thing you might try is NOT using awk to generate this
> hypothetical list of command-line arguments for mpv.  Why not simply
> generate the arguments in bash?  Then you don't need the
> serialize/deserialize steps.
>
> /me looks at the awk command from hell one more time.
>
> It appears that you're stripping the extension from each input filename
> and looking for other files that have the same "base" part with
> different extensions.  Bash is fully capable of doing that all on its
> own, without calling awk.
>
> myfunc() {
>   local i args base
>   for i; do
>     args=()
>     base=${i%.*}
>     [[ -f $base.foo ]] && args+=(--foo "$base.foo")
>     [[ -f $base.bar ]] && args+=(-b -a -r "$base.bar")
>     ...
>     mpv --static --arguments "${args[@]}" "$i"
>   done
> }
>
> Maybe something like this?
>
> There are lots of possibilities, but only someone who knows what the
> actual goal is can decide the best one.
>

Works like a charm (I don't have filenames with newlines). Thanks!
With a basename program installed as a core utility I never would have
remembered that bash could do it independently unless you had said
something.
Sorry to drive you to the brink of insanity. :)

I'm still a bit curious why printing a quoted filename from awk will not
work -- even when it has no spaces.
ls -- $( awk -v z="EXAMPLE" 'BEGIN{ print "\"" z "\"" }' )
Oh, wait a second. The file names quotes are being treated as part of the
filename and not being stripped. OTOH: If I don't include quotes
filenames with spaces cease to work correctly. So why is only partial
parameter expansion occurring?


Thanks again,
David



reply via email to

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