8
\$\begingroup\$

I will start by saying I have gotten this to work, and the question is about how improve the script to make it better/faster.

I need to compare a series of files to each other. Let's say I have the below files:

filename0   filename1   filename2

What I have done is:

Z=0 # Beginning number
Y=2 # Final number

X=$Z # Initial file number
((W=Y+1)) # Number for ranges

while [[ $Z -lt $W ]]
do
    while [[ $X -lt $W ]] 
    do
        obabel filename$Z.xyz -oconfabreport -xf filename$X.xyz -xr 0.2 > Results.$Z.$X
    ((X=X+1))
    done
    ((Z=Z+1))
    ((X=Z))
done

It compares files like this:

filename0 filename0
filename0 filename1
filename0 filename2
filename1 filename1
filename1 filename2
filename2 filename2

I am using openbabel's confabreport tool to find RMSD of structures. Is there a better way of doing this in bash scripting? Such as skipping a self comparison or ones that have already been compared? Or just a faster way of achieving the same thing? Please let me know if I need to provide any additional information, or if this question would be better somewhere else.

\$\endgroup\$

1 Answer 1

8
\$\begingroup\$

Welcome to Code Review!

Shellcheck

Use the amazing shellcheck utility to verify for common practices when writing bash/shell scripts. It reports missing shebang.

Loop using seq

Since you know the lower and upper bounds, and those are pure integers, use the seq command to iterate through them. You won't need to do custom increments and variable swaps.

Inner loop

Begin your inner loop with a value starting from current outer loop value + 1.

Variable

Using more descriptive variable names helps in understanding your code.

Parallelization

To achieve faster results, you can maybe use parallel to do the diff comparison for different files. If the set of files are small, you can also run the obabel tool in background, or disown the command from script entirely (depending on your requirements).


#!/bin/bash

LOWER_BOUND=0
UPPER_BOUND=2

for i in $(seq "$LOWER_BOUND" "$UPPER_BOUND")
do
    ((INNER_START=i+1))
    for j in $(seq "$INNER_START" "$UPPER_BOUND")
    do
        obabel "filename${i}.xyz" -oconfabreport -xf "filename${j}.xyz" -xr 0.2 > "Results.${i}.${j}"
    done
done

I'll leave parallelization to your own implementation. You can refer this excellent demonstration of parallel command.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the welcome! And thanks for the thorough response as well! \$\endgroup\$ Oct 12, 2020 at 3:29

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.