I'd like to write a script that reads a file and passes every line as options (or "option arguments") to a command, like this:
command -o "1st line" -o "2nd line" ... -o "last line" args
What's the simplest way of doing this?
I'd like to write a script that reads a file and passes every line as options (or "option arguments") to a command, like this:
command -o "1st line" -o "2nd line" ... -o "last line" args
What's the simplest way of doing this?
# step 1, read the lines of the file into a shell array
mapfile -t lines < filename
# build up the command
cmd_ary=( command_name )
for elem in "${lines[@]}"; do
cmd_ary+=( -o "$elem" )
done
cmd_ary+=( other args here )
# invoke the command
"${cmd_ary[@]}"
Here is one possibility:
$ cat tmp
1st line
2nd line
3rd line
4th line
$ command $(sed 's|.*|-o "&"|' tmp | tr '\n' ' ')
As glennjackman points out in the comments, word splitting can be circumvented by wrapping in eval, though the security implications of doing so should be appreciated:
$ eval "command $(sed 's|.*|-o "&"|' tmp | tr '\n' ' ')"
Edit: Combining my suggestion of using sed
to assemble arguments with glenn jackman's mapfile
/readarray
approach gives the following concise form:
$ mapfile -t args < <(sed 's|.*|-o\n&|' tmp) && command "${args[@]}"
As a trivial demonstration, consider the aforementioned tmp
file, the command grep
, and the file text
:
$ cat text
some text 1st line and
a 2nd nonmatching line
some more text 3rd line end
$ mapfile -t args < <(sed 's|.*|-e\n&|' tmp) && grep "${args[@]}" text
some text 1st line and
some more text 3rd line end
$ printf "%s\n" "${args[@]}"
-e
1st line
-e
2nd line
-e
3rd line
-e
4th line
printf "%s\n"
-- instead of receiving 8 arguments (-o
1st line
...), this technique will give the command 12 arguments containing literal quote chars (-o
"1st
line"
-o
"2nd
line"
etc). You could do eval "command $(sed ...)"
but that's nasty and fragile.
– glenn jackman
Nov 08 '17 at 20:41
eval
would be needed to avoid the word splitting problem; your command array-based approach is better for general use.
– user001
Nov 08 '17 at 21:05