Use associative array to map part of filename to colors

Advertisements

I am processing 5 filles with the following filenames

MD_6nax_DPPC_120A.pdb  MD_6nax_DOPC_120A.pdb  MD_6nax_POPC_120A.pdb
MD_6nax_DOPE_120A.pdb  MD_6nax_POPE_120A.pdb

from this data I need only the part of the filename after the second "_" lile DPPC, DOPE etc. I need to associate each of these IDs with specific color and print the corresponded color for corresponded ID, in the following fashion

for pdb in "${input}"/*.pdb ; do
pdb_name=$(basename "${pdb}")
pdb_name="${pdb_name/.pdb}"
declare -A assArray=( [DPPC]=yellow [DOPE]=blue [POPE]=white .. [POPC]=black )
pdb_title="${pdb_name/_120A/}"
pdb_title="${pdb_title/MD_6nax_/}"
echo this is ID of the file : $pdb_title which color is "${!assArray[@]}"
done

>Solution :

You don’t need to use indirect expression, i.e. of ${!array[@]}, but just use a array reference with the extracted substring. An associative array is basically a hash-map data structure, you look-up the value using the key, so as such a simple reference in the array would suffice.

A simple way to achieve your requirement would be to do

input=(MD_6nax_DPPC_120A.pdb  MD_6nax_DOPC_120A.pdb  MD_6nax_POPC_120A.pdb
MD_6nax_DOPE_120A.pdb  MD_6nax_POPE_120A.pdb)

declare -A assArray=([DPPC]=yellow [DOPE]=blue [POPE]=white [POPC]=black )

# The example uses the files from an array, but you can use the actual glob 
# in your example
for pdb in "${input[@]}"; do 
    # Needed in actual case with files, when the glob expansion fails
    # The loop terminates gracefully
    [ -f "$pdb" ] || continue 
    # Parameter expansion syntax to extract the middle part
    fname="${pdb%_*}"
    fname="${fname##*_}"
    printf '%s\n' "${assArray[$fname]}"
done

As you can see above, you don’t need to re-declare the colors array every time in the loop iteration.

Leave a ReplyCancel reply