1

I need to read a file and split every line into a domain and a application string

domain.com-backend
domain.com-frontend

For each line I need to call a docker build command (echo just to see the command):

cat $FILE | grep '-' | xargs -I {} echo docker build -t {full} -f apps/{domain}/{application}/Dockerfile .

So in the example I would expect the output

docker build -t domain.com-backend -f apps/domain.com/backend/Dockerfile .
docker build -t domain.com-frontend -f apps/domain.com/frontend/Dockerfile .
user3142695
  • 15,844
  • 47
  • 176
  • 332
  • 1
    Why not use `while` loop and `read` command ? – Digvijay S Sep 13 '20 at 07:02
  • @DigvijayS Did not think about it. I need to call the command in a CI, so I used before something like this as a one liner without building a 'real' script. – user3142695 Sep 13 '20 at 07:04
  • Yes, you can write in one line. Update my answer – Digvijay S Sep 13 '20 at 07:11
  • 1
    is using xargs so important? why not use awk ? – OznOg Sep 13 '20 at 07:14
  • If you use xargs, you could reach having a hard to read/modify command, in order to modify arguments you have to do something like this: https://stackoverflow.com/questions/45895071/how-to-use-substitution-in-xargs . A while loop can easily be written as one-liner too, if this is your concern, it's the same. – thanasisp Sep 13 '20 at 07:55

3 Answers3

1

You can do it with this loop:

while read -r x; do
    echo docker build -t "$x" -f "apps/${x/-/\/}/Dockerfile" .
done < "$FILE"

Remove echo after testing.

See more for bash parameter expansion


In case you want to first filter the file, e.g. there are more lines into there and you want first to grep "-" like in your example, you could use this syntax (bash only):

while read -r x; do
    echo docker build -t "$x" -f "apps/${x/-/\/}/Dockerfile" .
done < <(grep "-" "$FILE")
thanasisp
  • 5,855
  • 3
  • 14
  • 31
0

Try

while IFS= read -r line
do
  echo  docker build -t ${line} -f apps/$(cut -d'-' -f1  <<<${line})/$(cut -d'-' -f2 <<<${line})/Dockerfile .
done < "${FILE}"

Demo :

$while IFS= read -r line
> do
>   echo  docker build -t ${line} -f apps/$(cut -d'-' -f1  <<<${line})/$(cut -d'-' -f2 <<<${line})/Dockerfile .
> done  < test.txt 
docker build -t domain.com-backend -f apps/domain.com/backend/Dockerfile .
docker build -t domain.com-frontend -f apps/domain.com/frontend/Dockerfile .
$cat test.txt 
domain.com-backend
domain.com-frontend

Edit : One liner

while IFS= read -r line; do   echo  docker build -t ${line} -f apps/$(cut -d'-' -f1  <<<${line})/$(cut -d'-' -f2 <<<${line})/Dockerfile . ; done < "${FILE}"
Digvijay S
  • 2,665
  • 1
  • 9
  • 21
0

Split the file on - while reading and just invoke your command:

while IFS='-' read -r dom app; do
   docker build -t "$dom-$app" -f "apps/$dom/$app/Dockerfile .
done < "$file"

Read: bashfaq how to read a file field by field

Or you could use xargs, if you want:

sed 's/^\(.*\)-\(.*\)$/\1-\2 \1 \2/' "$file" |
xargs -n3 sh -c 'docker build -t "$1" -f "apps/$2/$3/Dockerfile"' _

or even:

sed 's@^\(.*\)-\(.*\)$@\1-\2 -f apps/\1/\2/Dockerfile@' "$file" |
xargs -n3 docker build -t
KamilCuk
  • 120,984
  • 8
  • 59
  • 111