Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to increment an integer while passing a multi-line string to a command using "Here tag" in bash

I have a piece of code that looks similar to this:

index=SOME_INTEGER
SOME_COMMAND <<EOF
subcommand1
${index} subsubcommand1
subcommand2
$((${index}+1)) subsubcommand2
subcommand3
$((${index}+2)) subsubcommand3
subcommand4
$((${index}+3)) subsubcommand4
subcommand5
$((${index}+4)) subsubcommand5
EOF

This method of manually adding one more to ${index} for each new subcommand is quite tedious, and not very practical if i need to rearrange the order/delete lines (the subcommand1 line must precede the subsubcommand1 line and the indexes must be given from lowest to highest), so i was wandering if there was a simple way to increment ${index} between <<EOF and EOF without referencing an exact number, or if there was an alternative way to pass the subcommands to SOME_COMMAND that would allow for this.

I have tried to give various commands like the following but they have not worked:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

$((index=$((index+1))))
$((index=index+1))
$((index+=1))
$((index++))

>Solution :

First: If you switch from a postincrement to a preincrement, your original code works. That is:

SOME_COMMAND() { cat; }
 
index=5
 
SOME_COMMAND <<EOF
subcommand1
${index} subsubcommand1
subcommand2
$((++index)) subsubcommand2
subcommand3
$((++index)) subsubcommand3
subcommand4
$((++index)) subsubcommand4
subcommand5
$((++index)) subsubcommand5
EOF

properly emits as output:

subcommand1
5 subsubcommand1
subcommand2
6 subsubcommand2
subcommand3
7 subsubcommand3
subcommand4
8 subsubcommand4
subcommand5
9 subsubcommand5

If that didn’t work, though, the easy, surefire thing to do here would be to write a function that generates your desired input. You can then either expand that function into a heredoc or herestring (if SOME_COMMAND needs its input to be seekable), or use it directly as a process substitution (if SOME_COMMAND only needs its input to be streamable).

input_for_SOME_COMMAND() {
  local index mainCommand
  index=$1; shift || return
  for arg; do
    printf '%s\n' "$arg" "$((index++)) sub$arg"
  done
}

SOME_COMMAND <<<"$(input_for_SOME_COMMAND 1 subcommand{1,2,3,4,5})"

See this working in an online sandbox at https://ideone.com/XOUauQ

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading