0

I am trying to write a bash script that can iterate through two folders, and run the files into a python program. The python program takes two input files (corresponding ones from each folder) and outputs a single file.

It looks a bit like this:

folder 1/
    Run_1.out
    Run_2.out
    Run_3.out
    ...
folder 2/
    Sym_1.g0.out
    Sym_2.g0.out
    Sym_3.g0.out
    ...

The python program takes in corresponding inputs (e.g. Run_1.out and Sym_1.g0.out) and outputs a file as such:

    NOCI.py Run_1.out Sym_1.g0.out outputfile

The python program works fine when used via the terminal with a single pair of files, but since I've got 360 pairs I figured I should use a script. So far I've tried writing two for loops, but it doesn't seem to work:

    #!/bin/bash
    FILE1=*.out
    FILE2=*.g0.out
    for i in $FILE1
    do
        for j in $FILE2
            do
                NOCI.py $i $j ${i}_${outputfile}
        done
    done
  • Shouldn't you specify the directory name when you define the files in FILE1 and FILE2? – unxnut Sep 7 '18 at 17:22
  • Hi and welcome. Is the second file always named the same as the first file, substituting Run with Sym? – Andy Dalton Sep 7 '18 at 17:25
  • @unxnut: yes the directory names are specified - just didn't include them in the example! – Plasmid Sep 7 '18 at 18:14
  • @AndyDalton: they are both .out files, but are located in the different directories. I could change the file names if that's an issue! – Plasmid Sep 7 '18 at 18:15
2

Matching folder 1/Run_1.out to folder 2/Sym_1.g0.out, and so on for 360 pairs:

for n in {1..360}
do
    NOCI.py "folder 1/Run_$n.out" "folder 2/Sym_$n.g0.out" outputfile
done

Or if the paired files are not in sequential order, you can pick off the Run_N.out files and associate a corresponding Sym_N.g0.out file:

for r in "folder 1/Run_"*.out
do
    n="${r#folder 1/Run_}"; n="${n%.out}"
    s="folder 2/Sym_$n.out"
    NOCI.py "$r" "$s" outputfile
done
|improve this answer|||||
0

zsh would be more suited than bash for this kind of task:

#! /bin/zsh -
files1=(1/*.out(n)) files2=(2/*.go.out(n))
for f1 f2 (${files1:^files2}) NOCI.py $f1 $f2 3/$f1:t:r+$f2:t
  • (n) sorts the globs numerically so they are processed in numerical order (where Run_10 comes between Run_9 and Run_11 instead of between Run_1 and Run_2 without it).
  • ${array1:^array2}: zips two arrays
  • $file:t: tail part of the file (base name)
  • $filr:r: root part (remove extension).

So we end up running:

NOCI.py 1/Run_1.out 2/Sym_1.g0.out 3/Run_1+Sym_1.g0.out
NOCI.py 1/Run_2.out 2/Sym_2.g0.out 3/Run_2+Sym_2.g0.out
...
|improve this answer|||||
0

With GNU Parallel you can do this:

parallel NOCI.py {1} {2} {1.}{2.}.output ::: Folder1/* ::: Folder2/*

It will default to run one job per CPU thread in parallel.

To see what will be run use --dry-run:

parallel --dry-run NOCI.py {1} {2} {1.}{2.}.output ::: Folder1/* ::: Folder2/*

GNU Parallel is a general parallelizer and makes is easy to run jobs in parallel on the same machine or on multiple machines you have ssh access to.

If you have 32 different jobs you want to run on 4 CPUs, a straight forward way to parallelize is to run 8 jobs on each CPU:

Simple scheduling

GNU Parallel instead spawns a new process when one finishes - keeping the CPUs active and thus saving time:

GNU Parallel scheduling

Installation

For security reasons you should install GNU Parallel with your package manager, but if GNU Parallel is not packaged for your distribution, you can do a personal installation, which does not require root access. It can be done in 10 seconds by doing this:

$ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
   fetch -o - http://pi.dk/3 ) > install.sh
$ sha1sum install.sh | grep 3374ec53bacb199b245af2dda86df6c9
12345678 3374ec53 bacb199b 245af2dd a86df6c9
$ md5sum install.sh | grep 029a9ac06e8b5bc6052eac57b2c3c9ca
029a9ac0 6e8b5bc6 052eac57 b2c3c9ca
$ sha512sum install.sh | grep f517006d9897747bed8a4694b1acba1b
40f53af6 9e20dae5 713ba06c f517006d 9897747b ed8a4694 b1acba1b 1464beb4
60055629 3f2356f3 3e9c4e3c 76e3f3af a9db4b32 bd33322b 975696fc e6b23cfb
$ bash install.sh

For other installation options see http://git.savannah.gnu.org/cgit/parallel.git/tree/README

Learn more

See more examples: http://www.gnu.org/software/parallel/man.html

Watch the intro videos: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Walk through the tutorial: http://www.gnu.org/software/parallel/parallel_tutorial.html

Read the book: https://doi.org/10.5281/zenodo.1146014

Sign up for the email list to get support: https://lists.gnu.org/mailman/listinfo/parallel

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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