LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (https://www.linuxquestions.org/questions/linux-general-1/)
-   -   Generating two bash arguments from 'ls' (https://www.linuxquestions.org/questions/linux-general-1/generating-two-bash-arguments-from-ls-889720/)

mzh 07-03-2011 04:49 PM

Generating two bash arguments from 'ls'
 
Dear Forum
Say I have a directory containing the following files.
Code:

1-res-opt-I189N-0001.pdb
1-res-opt-I189N-0002.pdb
1-res-opt-I189N-0003.pdb
1-res-opt-I189N-0004.pdb
1-res-opt-I189N-0005.pdb
1-res-opt-I189N-0006.pdb
1-res-opt-I189N-0007.pdb
1-res-opt-I189N-0008.pdb
1-res-opt-I189N-0009.pdb
1-res-opt-I189N-0010.pdb
3-res-opt-I189N-0001.pdb
3-res-opt-I189N-0002.pdb
3-res-opt-I189N-0003.pdb
3-res-opt-I189N-0004.pdb
3-res-opt-I189N-0005.pdb
3-res-opt-I189N-0006.pdb
3-res-opt-I189N-0007.pdb
3-res-opt-I189N-0008.pdb
3-res-opt-I189N-0009.pdb
3-res-opt-I189N-0010.pdb

What I want is something like:
Code:

for i in *.pdb
do
python my_script.py 1-res-opt-I189N-00{1..10}.pdb 3-res-opt-I189N-00{1..10}.pdb
done

such that always the two files with corresponding index are submitted together to the Python script.
How do I do that?
Thanks for any hints.

colucix 07-03-2011 04:56 PM

If you have bash 4 you can use extended brace expansion with zero-padded numbers:
Code:

for i in {0001..10}
do
  python my_script.py 1-res-opt-I189N-$i.pdb 3-res-opt-I189N-$i.pdb
done

Otherwise use printf and command substitution:
Code:

for i in {1..10}
do
  python my_script.py 1-res-opt-I189N-$(printf "%04d" $i).pdb 3-res-opt-I189N-$(printf "%04d" $i).pdb
done

In any case the iteration variable of the loop should be a number, not the whole filename. Hope this helps.

mzh 07-03-2011 05:19 PM

more than helpful. Thanks.

David the H. 07-04-2011 12:46 AM

For the record, this is what your original code does...
Code:

for i in *.pdb
do
python my_script.py 1-res-opt-I189N-00{1..10}.pdb 3-res-opt-I189N-00{1..10}.pdb
done

"for i in *.pdb" first sets the variable "i" to each individual filename in the directory in turn. But then it's never used anywhere.

Inside the loop you have a line with brace expansions inserted. These get expanded before execution, so you get a single command that looks like this:
Code:

python my_script.py 1-res-opt-I189N-001.pdb 1-res-opt-I189N-002.pdb 1-res-opt-I189N-003.pdb 1-res-opt-I189N-004.pdb 1-res-opt-I189N-005.pdb 1-res-opt-I189N-006.pdb 1-res-opt-I189N-007.pdb 1-res-opt-I189N-008.pdb 1-res-opt-I189N-009.pdb 1-res-opt-I189N-0010.pdb 3-res-opt-I189N-001.pdb 3-res-opt-I189N-002.pdb 3-res-opt-I189N-003.pdb 3-res-opt-I189N-004.pdb 3-res-opt-I189N-005.pdb 3-res-opt-I189N-006.pdb 3-res-opt-I189N-007.pdb 3-res-opt-I189N-008.pdb 3-res-opt-I189N-009.pdb 3-res-opt-I189N-0010.pdb
...which you then execute over and over again, once for each file in the directory.


As colucix demonstrated, generate the list of files you want to use (or in this case a sequence of numbers that can be used inside the loop to match filenames) first, then feed that to the for loop and use the variable set by it to access them one at a time.


By the way, for zero padding in bash 3, you could also simply do something like this:
Code:

for i in 000{1..9} 0010 ; do
See here for more on how to do zero padding:
http://mywiki.wooledge.org/BashFAQ/018

mzh 07-06-2011 09:24 AM

@david the h.:
thanks a lot. very informative post.
kind regards


All times are GMT -5. The time now is 02:01 PM.