How to insert a string and variable at specified position in command in bash?

I currently have a loop that reads all .bam files in a directory (wont always be 4 like in this example,
into $id . What I am trying to do, unsucessfully, is create specific new lines in an exsisting command using
each $id . Each new line would be:

--bam ${id} \

Tried

p=$dir
/path/to/xxx.py \
text="$(--bam ${id \})"
text="${text:0:p}j${text:p}"  ## insert text for each $p
     --ref /path/to/file \
     --run /ptah/to/data

directory

s1.bam
s2.bam
s3.bam
s4.bam

standard command

/path/to/xxx.py \
     --bam ${id}.bam \
     --ref /path/to/file \
     --run /ptah/to/data

desired command

/path/to/xxx.py \
     --bam s1.bam \
	 --bam s2.bam \
	 --bam s3.bam \
	 --bam s4.bam \
	 --ref /path/to/file \
     --run /path/to/data

Not sure I fully understand, and your "Tried" block seems to be gobbledigook, but how about

while IFS="" read -r LN
  do    [ "$LN" = "${LN##*id}" ] && echo "$LN" || for FN in *.bam
                                                    do echo "     -- bam $FN \\"
                                                    done
  done < file
/path/to/xxx.py \
     -- bam s1.bam \
     -- bam s2.bam \
     -- bam s3.bam \
     -- bam s4.bam \
     --ref /path/to/file \
     --run /ptah/to/data
 

EDIT: or

ls *.bam | awk 'NR == FNR {T = T DL "     --bam " $0 " \\"; DL = RS; next} /id/ {print T; next} 1' - file
1 Like

I am trying to insert each $id into the standard command below above the ref following the format -- bam ${id} \ . There won't always be
4 $id , that will change each time. Maybe storing each $id in a variable and then inserting that into the command? Thank you :).

insert=$(awk -v fn=--bam $id \'
   { 
     if( index( $0, fn ) )
       print;
   }')
/path/to/xxx.py \
${insert}
--ref /path/to/file \
--run /path/to/data

echo $id

s1.bam
s2.bam
s3.bam
s4.bam

standard command

/path/to/xxx.py \
--bam ${id} \
--ref /path/to/file \
--run /path/to/data

desired command using all 4 .bam in id on a seperate line

/path/to/xxx.py \
--bam ${id} \
--bam ${id} \
--bam ${id} \
--bam ${id} \
--ref /path/to/file \
--run /path/to/data

That desired command is different from the one in post #1. What exactly and finally do you need?

Why the detour using $id in lieu of using the file names in the directory immediately?

1 Like

Do you want something more like:

printf -- "/path/to/xxx.py \\\\\n%s\n\t--ref /path/to/file \\\\\n\t--run /path/to/data\n" \                       # Set up the output format with fixed strings and an assignment for where the data goes
   "$(for bamfile in *.bam; do printf -- "\t\t--bam %s \\\\\n"    "${bamfile}"; done)"                            # Collect & list the data file lines here, tab indenting each with \t and finishing with the formatting to append the \ and the new-line
                                                                                                                  # This will get used in the above line as the input for the data.

Lots of escaping in the strings which makes it look a bit messy, but it seems to work for me. After creating dummy files as you have, I got the output:-

/path/to/xxx.py \
		--bam s1.bam \
		--bam s2.bam \
		--bam s3.bam \
		--bam s4.bam \
	--ref /path/to/file \
	--run /path/to/data

Does this do what you need?

Robin

3 Likes

The id contains the unique prefix of each bam, so the s1,s2,s3,s4 .

I am trying to insert each of those into the command in post 3. That is make the command dependent or conditional on id. So if there are 4 id then there are 4 --bam ${id} \ inserted and if there are 7 id then 7 --bam ${id} \ inserted in the command. There may be a better way that I am not thinking of. Thank you :).

Oh? Changing basic data again?

Be aware that a good, decent, stable, consistent specification helps everyone dealing with your request, saving time and efforts.

And, either of the three solutions given above can easily be adapted to your old and new and ever changing data (structures). This is left as an exercise to the interested reader.

1 Like

From my suggestion in post 5, I'm sure you can attempt to replace the sub-process on line 2 (the bit between $( and ) ) such that the output it creates uses a loop based on a counter to create the required number of rows, but then, however would would handle it if one of the files didn't exist?

Please give us the actual problem you are trying to solve, with the actual conditional, the actual logic and the actual files listed in the actual directory and we might actually be able to help you. Otherwise we're just guessing at what you need help with.

Thanks, in advance,
Robin

2 Likes

I apologize for the delay in response, the script works perfectly.... thank you very much :).