0

There are four files I am using here for this task: an input file, the file whose values I want to change, and two shell scripts. The first file, models_linearanalysis_Cep.dat is an input file that is organized as so:

1 0.020 0.700 5.4 1500 4000 2 0.020 0.700 5.4 1500 4050 3 0.020 0.700 5.4 1500 4100 4 0.020 0.700 5.4 1500 4150 5 0.020 0.700 5.4 1500 4200 

The columns from 1-6 are respectively organized as directory number (d_number), Z, X, mass, L, and Teff. I want to use the 6 values from every row to change the assignments of the variables in this second file inlist_rsp_Cepheid which has the variables:

 RSP_mass = 4.165d0 RSP_Teff = 6050 RSP_L = 1438.8d0 RSP_X = 0.73d0 RSP_Z = 0.007d0 log_directory='LOGS_1' photo_directory='photos_1' 

In this instance, the directory number (i.e. the number attached to LOGS_ and photos_) is 1.

In my first shell script, Inlists_Bash.sh, shown below I attempt to read values from the six columns of the file models_linearanalysis_Cep.dat here, which I intend to read into a second shell script inlist_changer.sh.

while read -ra fields; do for field in "${fields[@]}"; do bash inlist_changer.sh <<<"$field" done ./mk ./rn done < models_linearanalysis_Cep.dat 

Finally, with the second shell script inlist_changer.sh, I use the inputs to finally change the lines in inlist_rsp_Cepheid such that the variables have the appropriate values.

#!/bin/bash export OMP_NUM_THREADS=12 #used for testing variables #export mass=4.165d0 #export teff=6050 #export l=1438.8d0 #export x=0.73d0 #export z=0.007d0 #export d_number=2 #read in inputs from the Inlists_Bash.sh file read -p d_number z x mass l teff #inlist directory export MESA_INLIST="/home/nick/mesa-r11701/star/test_suite/rsp_Cepheid_grid/inlist_rsp_Cepheid" #change the lines in the MESA_INLIST file sed -i \ -e "s/^\([[:blank:]]*RSP_mass\).*/\1 = $mass/i" \ -e "s/^\([[:blank:]]*RSP_Teff\).*/\1 = $teff/i" \ -e "s/^\([[:blank:]]*RSP_L\).*/\1 = $l/i" \ -e "s/^\([[:blank:]]*RSP_X\).*/\1 = $x/i" \ -e "s/^\([[:blank:]]*RSP_Z\).*/\1 = $z/i" \ -e "s/^\([[:blank:]]*log_directory\).*/\1 = 'LOGS_$d_number'/i" \ -e "s/^\([[:blank:]]*photo_directory\).*/\1 = 'photos_$d_number'/i" \ "$MESA_INLIST" 

For the first row, I was expecting inlist_rsp_Cepheid to look like this:

 RSP_mass = 5.4 RSP_Teff = 4000 RSP_L = 1500 RSP_X = 0.700 RSP_Z = 0.020 log_directory='LOGS_1' photo_directory='photos_1' 

However, it is clear something is wrong with how I am reading the inputs between these files as I receive this instead:

 RSP_mass = RSP_Teff = RSP_L = RSP_X = RSP_Z = 4000 log_directory='LOGS_' photo_directory='photos_' 

Would someone please explain what I may be missing or doing incorrectly here?

1

1 Answer 1

2

Change Inlists_Bash.sh to this and pass all six values of the array at once to inlist_changer.sh:

#!/bin/bash while read -ra fields; do ./inlist_changer.sh "${fields[@]}" ./mk ./rn done < models_linearanalysis_Cep.dat 

Change inlist_changer.sh to use parameters $1 ... $6 instead of using read.
The -p in read is used to print a prompt string (d_number in your case) and you were only setting variable z in each of your calls.

#!/bin/bash export OMP_NUM_THREADS=12 mesa_inlist=/home/nick/mesa-r11701/star/test_suite/rsp_Cepheid_grid/inlist_rsp_Cepheid sed -i \ -e "s/^\([[:blank:]]*RSP_mass\).*/\1 = $4/i" \ -e "s/^\([[:blank:]]*RSP_Teff\).*/\1 = $6/i" \ -e "s/^\([[:blank:]]*RSP_L\).*/\1 = $5/i" \ -e "s/^\([[:blank:]]*RSP_X\).*/\1 = $3/i" \ -e "s/^\([[:blank:]]*RSP_Z\).*/\1 = $2/i" \ -e "s/^\([[:blank:]]*log_directory\).*/\1 = 'LOGS_$1'/i" \ -e "s/^\([[:blank:]]*photo_directory\).*/\1 = 'photos_$1'/i" \ "$mesa_inlist" 

Note: It's not clear where you need the exported variable OMP_NUM_THREADS.


Or put everything into one script:

#!/bin/bash export OMP_NUM_THREADS=12 mesa_inlist=/home/nick/mesa-r11701/star/test_suite/rsp_Cepheid_grid/inlist_rsp_Cepheid while read -ra fields; do sed -i \ -e "s/^\([[:blank:]]*RSP_mass\).*/\1 = ${fields[3]}/i" \ -e "s/^\([[:blank:]]*RSP_Teff\).*/\1 = ${fields[5]}/i" \ -e "s/^\([[:blank:]]*RSP_L\).*/\1 = ${fields[4]}/i" \ -e "s/^\([[:blank:]]*RSP_X\).*/\1 = ${fields[2]}/i" \ -e "s/^\([[:blank:]]*RSP_Z\).*/\1 = ${fields[1]}/i" \ -e "s/^\([[:blank:]]*log_directory\).*/\1 = 'LOGS_${fields[0]}'/i" \ -e "s/^\([[:blank:]]*photo_directory\).*/\1 = 'photos_${fields[0]}'/i" \ "$mesa_inlist" ./mk ./rn done < models_linearanalysis_Cep.dat 
4
  • Now, say I want to put all the LOGS_ and photos_ into directories: named LOGS_A. I and photos_A. I tried to change LOGS_${fields[0])} to LOGS_A/LOGS_${fields[0])}, but the LOGS_A directory is not even created and I get the error sed: -e expression #6, char 49:unkown option to 's'. How would you modify the script to do this? Commented May 18, 2020 at 17:20
  • 1
    The / is the separator for the substitution ("s/regexp/replacement/i"), either escape it as LOGS_A\/LOGS_${fields[0]} or change the separator to a different character ("s#regexp#replacement#i"). Commented May 18, 2020 at 17:40
  • One small question. Let's say I don't want to read all the rows in models_linearanalysis_Cep.dat, perhaps for example the last 5000 rows. I know that a for loop would be appropriate for this situation, but I am naive about the syntax. Woulf you simply replace while read -ra fields with for read -ra field in fields? Commented May 22, 2020 at 1:19
  • You can read the last N lines of a file with tail -nN file and you could change the last line to done < <(tail -n5000 models_linearanalysis_Cep.dat) using a process substitution <(...). Commented May 22, 2020 at 1:38

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.