1

I have a script find-files that produces paths that can contain space in lines

/foo bar
/abc

I want to convert these paths to arguments that get to pass to another command cmd like this:

cmd -f "/foo bar" -f "/abc"

I tried this

cmd $(find-files | sed 's/^/-f /')

But it passes paths containing space as multiple arguments.

and if I quote the substitution, the whole string gets passed as a single argument.

What's the correct way of doing that?

BTW, this is not the same question as asked here, which suggested eval. eval doesn't help with dealing spaces at all.

hgl
  • 2,034
  • 4
  • 21
  • 30

2 Answers2

2

Use a loop to build up the necessary array.

while IFS= read -r fname; do
  args+=(-f "$fname")
done < <(find-files)

cmd "${args[@]}"

This assumes that the file names cannot contain newlines, though, since read will treat such files as consecutive file names, not a single name. It's not clear if that is an issue for you, or if your find-files command can provide a safe alternative (such as output a null-separated list of file names, rather than lines).

chepner
  • 497,756
  • 71
  • 530
  • 681
-1

Put all your filenames in an array.

lst=( "/foo bar" /abc ) # quote as necessary

Then use printf to insert the -f.

cmd $( printf ' -f "%s"' "${lst[@]}" ) # leading space helps

For example,

$: echo $( printf ' -f "%s"' "${lst[@]}" )
-f "/foo bar" -f "/abc"

The leading space in front of the -f simplifies a bit.
Without it you get:

$: echo $( printf '-f %s' "${lst[@]}" )
bash: printf: -f: invalid option
printf: usage: printf [-v var] format [arguments]


EDIT:

Added double quotes inside the printf format.

Paul Hodges
  • 13,382
  • 1
  • 17
  • 36