1

I'm not a programmer at all, but I need to write a script to cut a file and produce a multidimensional array from this file.

I'm a chemist, so my array should be something like:

[pe][pH][element][concentration].

This way, I'll be able to plot concentration change for a single element with pH and pe.

So I wrote this script to cut my input file and index pe, pH and species, but now I'm stuck. I have no idea how to complete it.

    #!/bin/bash
    inputFile='test.inp'

    awk '/Distribution of species/ {f=1} /Saturation indices/ {f=0} f' $inputFile > distriPack.inout
   csplit -z -f distri_ distriPack.inout /Distribution/ {*}
   sed -i '1,5d; $d' distri_*
   sed -i 's/^ *//' distri_*
   cut -d ' ' -f1 distri_* | sort | uniq > especes.inp
   grep -E "pH  =   " $inputFile | cut -d '=' -f 2 | cut -d ' ' -f 4 > ph.inp
   grep -E "pe  =   " $inputFile | cut -d '=' -f 2 | cut -d ' ' -f 4 > pe.inp

   declare -a tableVariable=(ipe ipH ies)

  ipe=0 
  tablepe=0
  for pe in cat "$pe.inp"
  do 
      if ([ $ipe -eq 0 ] || pePrev=pe)
          then 
           tablepe=$((tablepe+1))
           ipe=$((ipe+1))
           pePrev=$pe
           fi
             ipH=0
             tablepH=0
             for pH in cat "$pH.inp"
             do 
             if ([ $ipH -eq 0 ] || pHPrev=pH )
             then 
             tablepH=$((tablepH+1)) > tablepH.inp
             ipH=$((ipH+1))
             pHPrev=$pH
             fi
                ies=0
                tablees=0
                for espece in cat "$espece.inp"
                do
                    if ([ $ies -eq 0 ] || especePrev=espece )
                    then 
            #                       indEspece=0
            #                       for espece in distri_$pe
            #                       do 
            #                          if ([ $indEspece -eq 0 ])
                       maVariable= grep -E "espece" < distri_10  | cut -d ' ' -f 1 

                       ${tableVariable[ $((ipe)) $((ipH)) $((ies)) ]}=$((maVariable))
          #                     done            
                    ies=$((ies+1))
                    tablees=$((tablees+1))
                    especePrev=$espece
                    fi  
                    done
                   done

           done 

val=${monTableau[${i_pe} ${i_pH} ${es} ${pa}]}>monTableau.inp

I'll like to have something like : for [pe][pH][specie]=[0][12][15]

indexTable=concentration.

But I don't know how to say in bash for pe = i, pH = j and specie=k and do indexTable[i][j][k]=value of the second columns of the file Distri_(pe/pH index value) for the line corresponding to the specie of index k. Here you have "some" lines from my input file :

    >Initial solution 1. \newline
    >Description of solution 
    >pH = 0.0 
    >pe = 0.0 
    >Distribution of species 
    >Species Molality log Activity 
    >H+       1.1e+00 1.0e+00 
    >OH-      1.5e-14 9.5e-15 
    >Am+2     0.0e+00 0.0e+00


    >Initial solution 2. pe 0 pH 0.5 
    >Description of solution 
    >pH = 0.5 
    >pe = 0.0 
    >Distribution of species 
    >Species Molality Log Activity 
    >H+ 4.1e-01 3.1e-01 
    >OH- 4.5e-14 3.1e-14 
    >Am+2 0.0e+00 0.0e+00 

I'd like to get something like that : outputfile_[pe value].out where data would be ordered like that :

    >Column 1    C2 .....      Cn 
    >Specie\pH   0             n 
    >H+          [H+] at pH=0  [H+] at pH=n 

etc

6
  • Hi Nicolas. I'm thinking about to use awk to solve your issue, but I need some sample input (paste some lines of your input file, if possible) and the desired output for that sample. Commented Mar 6, 2017 at 18:44
  • Here you have "some" lines from my input file : Initial solution 1. Description of solution pH = 0.0 pe = 0.0 Distribution of species Species Molality log Activity H+ 1.1e+00 1.0e+00 OH- 1.5e-14 9.5e-15 Am+2 0.0e+00 0.0e+00 Commented Mar 7, 2017 at 9:04
  • Initial solution 2. pe 0 pH 0.5 Description of solution pH = 0.5 pe = 0.0 Distribution of species Species Molality Log Activity H+ 4.1e-01 3.1e-01 OH- 4.5e-14 3.1e-14 Am+2 0.0e+00 0.0e+00 I'd like to get something like that : outputfile_[pe value].out where data would be ordered like that : Column 1 C2 ..... Cn Specie\pH 0 n H+ [H+] at pH=0 [H+] at pH=n .... Commented Mar 7, 2017 at 9:04
  • Hi Nicolas. Can you please edit your question and put this information there? Here in the comments everything seems to be in the same line.. Is this the case? A formated input and desired output should point me to the right direction to help you... Commented Mar 7, 2017 at 20:11
  • Sorry @Nicolas, but I still don't understand what should be the final result and what fields should be put in what position in a multidimensional array... Commented Mar 8, 2017 at 12:48

1 Answer 1

0

emphasized textI'm not sure if you want to print the ">" sign in the output or if it exists in the input... Please, give me a feedback so I could make the corrections in the script.

This should do the job if the input and output are exactly as you described:

#!/usr/bin/awk
{
# Set the INDEX for each 'Initial Solution'
if ($1==">Initial"){
        gsub(/\./,"",$3);
        INDEX=$3;}

#Discard lines with 'Species' or 'Description'
if (($1==">Description")||($1==">Species")) next;

#Remove '>' from the first field
gsub(/>/,"",$1)

#Set the labels of the rows
PH[0]="Column"
PE[0]="Specie\\ph"
H[0]="H+"
OH[0]="OH-"
AM[0]="Am+2"

#Set other values (pH, pe, etc)
if ($1=="pH") PH[INDEX]=$3
if ($1=="pe") PE[INDEX]=$3
if ($1=="H+") H[INDEX]=$2" "$3
if ($1=="OH-") OH[INDEX]=$2" "$3
if ($1=="Am+2") AM[INDEX]=$2" "$3
}

# Print each array.
END {
for (i = 0; i <= INDEX; i++) printf("%s\t",i)
printf("\n")
for (i = 0; i <= INDEX; i++) printf("%s\t",PH[i])
printf("\n")
for (i = 0; i <= INDEX; i++) printf("%s\t",PE[i])
printf("\n")
for (i = 0; i <= INDEX; i++) printf("%s\t",H[i])
printf("\n")
for (i = 0; i <= INDEX; i++) printf("%s\t",OH[i])
printf("\n")
for (i = 0; i <= INDEX; i++) printf("%s\t",AM[i])
printf("\n")
}

Some notes:

  1. The first line (#!/usr/bin/awk) should point to the location of awk in your machine (try whereis awk at the prompt)
  2. At the final block, the \t inserts a 'tab' between the fields. You may replace it for \t\t for 2 tabs, a comma ',' or simply a space ' ' to fit your needs.
  3. Save this script and to use it, simply do: awk -f script.name.awk input.file.inp

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .