4

My use case is as follows.

file.txt

First arg: %s
Second %s arg,
Third %s

Run prog file.txt "one" "$(ls dir1/dir2)" "three"

Resulting in

First arg: one
Second file1 file2 file3 arg,
Third three

I first thought to use sed but that inevitably runs into problems when bash substitutions get read as format characters like this sed s/%1/$VAR/g -> sed s/%1/dir1/dir2/file1/g

I'm thinking I could iterate by lines and take the text before and after a substitute and just insert like

FIRST=$(sed "s/%s.*//" <<< $LINE)
SECND=$(sed "s/.*%s//" <<< $LINE)

echo "$FIRST $SUB $SECND"

Though that's limited to one sub per line and I would prefer a cleaner solution if it exists.

M__
  • 75
  • 5

2 Answers2

7

You could use printf with the whole file as the formatting string:

printf "$(< file.txt)\n" one two three

Notice that command substitution removes trailing newlines, so a separate \n is added back; see How to avoid bash command substitution to remove the newline character? for details.

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
  • Didn't know you could redirect files in this way. Very helpful. – M__ Feb 20 '21 at 03:50
  • 1
    @M_ Strictly speaking, the `$(< file.txt)`, which is equivalent to `$(cat file.txt)` (but faster), is not redirection. It is command substitution. – M. Nejat Aydin Feb 20 '21 at 04:05
2

Would you please try the following as prog:

#!/bin/bash

c=1                                     # counter for argv
nl=$'\n'                                # newline character
while IFS= read -r format; do           # read "file.txt" line by line
    (( c++ ))                           # increment the argv counter
    argv="${!c}"                        # obtain the argv indexed by "c"
    printf "${format}\n" "${argv//$nl/ }"
                                        # print the argv formatted by the line of "file.txt"
done < "$1"                             # "$1" is assigned to "file.txt"

The substitution "${argv//$nl/ }" just converts the newline characters included in the output of ls into whitespace characters.

tshiono
  • 21,248
  • 2
  • 14
  • 22