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

  • 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. – Daniel Vasconcelos Mar 6 '17 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 – Nicolas Schmitt Mar 7 '17 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 .... – Nicolas Schmitt Mar 7 '17 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... – Daniel Vasconcelos Mar 7 '17 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... – Daniel Vasconcelos Mar 8 '17 at 12:48
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

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.