2

I am trying to run a program using multiples interval as arguments. I am using a for loop in a shell script to do this. However, I only was capable of running this code step by step, as showed bellow. I would like to know if there is a way to run this command in a single command line. I just begin to learn the shell lenguage. I already tried some combineation of commands such as do and then, but withou sucess. Any kind of help is welcome.

Thank you,

for K in 1 $(seq 1 5000000 160000000)
    > do
    > J=$((K+5000000))
    > impute2 -phase -m ../impute2_chr1.map -g ../CHR1_17_04_17.gz -int $K $J -Ne 20000 -o phasing_CHR1_${K}_${J}
    > done

3 Answers 3

2
for K in 1 $(seq 1 5000000 160000000); do J=$((K+5000000)); impute2 -phase -m ../impute2_chr1.map -g ../CHR1_17_04_17.gz -int $K $J -Ne 20000 -o phasing_CHR1_${K}_${J};done

I find 'do' not requiring its own ; always a bit counter-intuitive, but otherwise it's easy to understand. 'then' and 'else' follow that same logic, by the way, as in:

if [[ 'x' == 'y' ]];then echo 'yes'; else echo 'no'; fi

To satisfy a comment: you use ; to replace the line breaks. With the exception of the 'do', 'else', 'then', as noted. When in doubt, create a simpler form of the thing, see where the ; should be used to have it work, then do the more complicated form.

Sign up to request clarification or add additional context in comments.

7 Comments

How does this answer the question? You literally just copied the code from the question and replaced newlines with ;
@123 The OP doesn't seem to be aware that you don't need to hit Enter after each part; this does show how to combine the parts into a single logical line, although the practical difference between the two is negligible.
He asked how to do it, so I showed him how to do it. How else would you show someone other than using their code, so they can see it work? The question didn't require any further information since obviously the only thing the person wasn't aware of is how to use ; to create a single line bash thing. His question was if it could be done in a single line, so I showed him how to do exactly that, using his code, which is always the best way to show something. It's not my fault that nothing more complicated was required to answer the question.
As for do, I suspect it is only there to make a for loop look like a do loop. Something like done is necessary to terminate the body, but unlike a while loop (in which the condition can be an arbitrary list of commands), a ; alone seems sufficient to terminate the sequence being iterated over. At least, anything other than do following the ; results in a syntax error. In a while loop, do is just a keyword that serves to terminate a command list, not a command itself, hence no semicolon necessary.
@Lizardx Fair enough, just thought it could use some more explanation.
|
0

In bash, different instructions are separated by either newlines \n or ;, but structuring your code on multiple lines makes it way easier to read and grasp faster, so I'd suggest leaving it on multiple lines except if you have specific needs but I can't think of any right now.

2 Comments

Thank you for the explanation. I would like to use a single command line because I am preparing some tutorials of how to use some programs for the team in my lab. As the majority of the person do not are familiar with command line options, a single command is better (even less understandable).
He didn't ask for your style comments. He asked how to achieve a goal. There are many reasons some of us like to have a multi-statement script on a single line.
0

Create a file called go in your HOME directory that looks like this:

#!/bin/bash
for K in 1 $(seq 1 5000000 160000000); do
  J=$((K+5000000))
  impute2 -phase -m ../impute2_chr1.map -g ../CHR1_17_04_17.gz -int $K $J -Ne 20000 -o phasing_CHR1_${K}_${J}
done

Now make that file executable (just do it one time) with:

chmod +x $HOME/go

Now you can run it as many times as you like by typing:

$HOME/go

If you want students to be able to run it, store it in /usr/local/bin/go and change $HOME to /usr/local/bin throughout.

2 Comments

He didn't ask how to do it in multiple lines in a script. He asked how to do it in a single line. In addition littering your HOME directory with scripts is not to be recommended. Finally, "students" won't have access to his usr/local/bin unless they're all on the same machine.
@RichieHH As far as I can tell $HOME/go is a single line, isn't it? Regarding "littering a HOME directory with scripts", I agree, however it was my opinion at the time of answering that 1) it was only a single script (so hardly "littering") and that 2) it wasn't worth the added confusion, for a self-confessed beginner, of creating a sub-directory for holding scripts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.