Home > Software design >  Is there a way to permute inside using to variables in bash?
Is there a way to permute inside using to variables in bash?

Time:12-15

I'm using the software plink2 (https://www.cog-genomics.org/plink/2.0/) and I'm trying to iterate over 3 variables.

This software admits an input file with .ped extention file and an exclude file with .txt extention which contains a list of names to be excluded from the input file.

The idea is to iterate over the input files and then over exclude files to generate single outputfiles.

  1. Input files: Highland.ped - Midland.ped - Lowland.ped
  2. Exclude-map files: HighlandMidland.txt - HighlandLowland.txt - MidlandLowland.txt
  3. Output files: HighlandMidland - HighlandLowland - MidlandHighland - MidlandLowland - LowlandHighland - LowlandMidland

The general code is:

plink2 --file Highland --exclude HighlandMidland.txt --out HighlandMidland
plink2 --file Highland --exclude HighlandLowland.txt --out HighlandLowland
plink2 --file Midland --exclude HighlandMidland.txt --out MidlandHighland
plink2 --file Midland --exclude MidlandLowland.txt --out MidlandLowland
plink2 --file Lowland --exclude HighlandLowland.txt --out LowlandHighland
plink2 --file Lowland --exclude MidlandLowland.txt --out LowlandMidland

To avoid repeating this code 6 different times I would like to use the variables listed above (1, 2 and 3) to create single output files. Outputfiles are a permutation with replacements of the inputfile names.

CodePudding user response:

Honestly, I think your current code is quite clear; but if you really want to write this as a loop, here's one possibility:

lands=(Highland Midland Lowland)
for (( i = 0 ; i < ${#lands[@]} ;   i )) ; do
  for (( j = i   1 ; j < ${#lands[@]} ;   j )) ; do
    plink2 --file "${lands[i]}" --exclude "${lands[i]}${lands[j]}.txt" --out "${lands[i]}${lands[j]}"
    plink2 --file "${lands[j]}" --exclude "${lands[i]}${lands[j]}.txt" --out "${lands[j]}${lands[i]}"
  done
done

and here's another:

lands=(Highland Midland Lowland)
for (( i = 0 ; i < ${#lands[@]} ;   i )) ; do
  for (( j = 0 ; j < ${#lands[@]} ;   j )) ; do
    if [[ "$i" != "$j" ]] ; then
      plink2 \
        --file "${lands[i]}" \
        --exclude "$lands[i < j ? i : j]}$lands[i < j ? j : i]}.txt" \
        --out "${lands[i]}${lands[j]}"
    fi
  done
done

. . . but one common factor between both of the above is that they're much less clear than your current code!

  • Related