Home > database >  How to pass parameters to a command in bash when run line by line?
How to pass parameters to a command in bash when run line by line?

Time:10-05

I have a file of parameters which I want to feed into a command in bash. Please note that I write the command below but the question isn't about the command, it's about how to pass the parameters from this file into the command.

The file, myfile.txt, looks like this:

3 rs523534 62297313 63097313
4 rs6365365 375800230 376600230
8 rs75466 63683994 64483994

I have a script to read each line and feed it into a command:

while read -r line; do

    plink --bfile mydata \
    --chr echo $line | awk '{print $1}' \
    --from-bp echo $line | awk '{print $3}' \
    --to-bp echo $line | awk '{print $4}' \
    --r2 \
    --ld-snp echo $line | awk '{print $2}' \
    --ld-window-kb 100000000 \
    --ld-window 100000000 \
    --ld-window-r2 0 \
    --out echo "processing/5_locuszoom/$line" | sed 's/ /_/g'

done < "myfile.txt"

This doesn't work:

awk: fatal: cannot open file `--to-bp' for reading (No such file or directory)
awk: fatal: cannot open file `--from-bp' for reading (No such file or directory)
awk: fatal: cannot open file `--r2' for reading (No such file or directory)
awk: fatal: cannot open file `--ld-window-kb' for reading (No such file or directory)

But if I run it manually, e.g.

plink --bfile mydata \
--chr 3 \
--from-bp 62297313 \
--to-bp 63097313 \
--r2 \
--ld-snp rs523534 \
--ld-window-kb 100000000 \
--ld-window 100000000 \
--ld-window-r2 0 \
--out 3_rs523534_62297313_63097313

It works fine.

Is there a way that I can better feed the variable information into the command so that it works?

CodePudding user response:

If you want to run a command inline to another command, you need to use a command substitution. So instead of --chr echo $line | awk '{print $1}' \ for example, you'd write --chr $( echo $line | awk '{print $1}' ) \.

But in this case it's not necessary, since read can already split the data for you.

#!/bin/bash
while read -r arg1 arg2 arg3 arg4 ; do
  <do things with your args here>
done <"myfile.txt"

read will split each line based on the contents of IFS and populate each name you give it with the corresponding token from the split line.

CodePudding user response:

Probably what you want is, in pure bash

#!/bin/bash

while read -ra args; do
    out="${args[*]}"
    plink --bfile mydata       \
      --chr "${args[0]}"       \
      --from-bp "${args[2]}"   \
      --to-bp "${args[3]}"     \
      --r2                     \
      --ld-snp "${args[1]}"    \
      --ld-window-kb 100000000 \
      --ld-window 100000000    \
      --ld-window-r2 0         \
      --out "processing/5_locuszoom/${out// /_}"
done < "myfile.txt"

Use of awk and sed for this task is superfluous.

  • Related