0

So I am looking to edit a number of bits of a file prior to using it as an input file for model simulations. At the moment I am passing it back and forth between a couple of temporary files (it was a bit buggy when I tried to write to the same temporary file) before finally making a file I can use to run the model. Is there a way to get all this alterations made simultaneously? I reckon doing it the way I am now is probably quite inefficient. Example of code below:

sed -e "s/9000000.0/${naerval}/" MC_NAMELIST_Pin14_Run3.IN > /tmp/temp1.in 
                #sed is away to change a string in a text file
sed -e "s/8000000.0/${sig_aer}/" /tmp/temp1.in > /tmp/temp2.in

sed -e "s/7000000.0/${d_aer}/" /tmp/temp2.in > /tmp/temp1.in

sed -e "s/6000000.0/${t_twall}/" /tmp/temp1.in > /tmp/temp2.in

sed -e "s/5000000.0/${RH}/" /tmp/temp2.in > /tmp/temp1.in

sed -e "s/4000000.0/${Therm_Coeff}/" /tmp/temp1.in > /tmp/temp2.in

sed -e "s/3000000.0/${press_decay}/" /tmp/temp2.in > /tmp/temp1.in

sed -e "s/2000000.0/${kappa}/" /tmp/temp1.in > /tmp/NAMELIST.IN

./main.exe /tmp/NAMELIST.IN 

I have additionally attempted replacing this code with:

sed -i.bak s~9000000.0~${naerval}~;s~8000000.0~${sig_aer}~;s~7000000.0~${d_aer}~;s~6000000.0~${t_twall}~;s~5000000.‌0~${RH}~;s~4000000.0~${Therm_Coeff}~;s~3000000.0~${press_decay}~;s~2000000.0~${ka‌​ppa}~;" MC_NAMELIST_Pin14_Run3.IN > /tmp/NAMELIST.IN

./main.exe /tmp/NAMELIST.IN 

However, this causes an error in main.exe while the original code does not. I assume therefore that this code does not alter MC_NAMELIST_Pin14_Run3.IN in the expected way.

  • Definitely looks that way, I didn't find it when I went hunting for it though. Baybe it needs a retitle/retag? In fairness I'm finding the answer to that question pretty difficult to read probably because of the example being given. – Reluctant_Linux_User Dec 09 '14 at 12:32
  • I found it using a well-known search engine but I'm surprised it didn't come up when you were writing the question. It's possibly not the best duplicate, I'm sure there are several. Anyway, it looks like the answers there are in agreement with what you have here. – Tom Fenech Dec 09 '14 at 12:36
  • Interesting: best guess you're doing better at searching for this kind of stuff than a rank beginner, that seems plausible. Maybe it's because I was searching for bash? – Reluctant_Linux_User Dec 09 '14 at 12:39
  • For the record, my search was "sed multiple commands". – Tom Fenech Dec 09 '14 at 12:42

3 Answers3

4

You can combine several sed commands like this:

sed -i.bak "s/9000000.0/${naerval}/; s/8000000.0/${sig_aer}/" /tmp/temp1.in
  • i.bak will enable inline editing and save original file with .bak extension
  • Keep in mind that your replacement strings cannot create a slash or new line.

You can use an alternate delimiter like this:

sed -i.bak "s~9000000.0~${naerval}~; s~8000000.0~${sig_aer}~" /tmp/temp1.in
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • Sorry, I'm not that good at programming so please bear with me. Will this save to the file /tmp/temp1.in or will it save to i.bak (presumably in the current directory)? – Reluctant_Linux_User Dec 09 '14 at 12:34
  • It will save the replaced data in `/tmp/temp1.in` itself. – anubhava Dec 09 '14 at 12:35
  • 1
    And create a backup of the original file as `/tmp/temp1.in.bak` – Jonathan Wakely Dec 09 '14 at 12:40
  • Yes that is correct, it saves a backup with the name: `/tmp/temp1.in.bak` – anubhava Dec 09 '14 at 12:41
  • I'm going to let the current run finish and then I'll try it out. – Reluctant_Linux_User Dec 09 '14 at 12:41
  • Not yet... hitting error messages. – Reluctant_Linux_User Dec 10 '14 at 08:40
  • That is very informative. What errors you're getting? – anubhava Dec 10 '14 at 08:43
  • The model runs with the original code, with the new code I get: "At line 54 of file MAIN.f90 (unit = 8, file = '/tmp/NAMELIST.IN')" I may not have applied the suggested solution correctly. I replaced the code in the question (apart from the last line) as follows:"sed -i.bak "s~9000000.0~${naerval}~; s~8000000.0~${sig_aer}~;s~7000000.0~${d_aer}~;s~6000000.0~${t_twall}~;s~5000000.0~${RH}~;s~4000000.0~${Therm_Coeff}~;s~3000000.0~${press_decay}~;s~2000000.0~${kappa}~;" MC_NAMELIST_Pin14_Run3.IN > /tmp/NAMELIST.IN" – Reluctant_Linux_User Dec 10 '14 at 08:55
  • I don't know how to make it look like code in a comment so the outer "" are not in the code. Thought it was worth clearing that up. I've set the next run going so there will be a 4 hour lag time between now and my being able to do anything again. – Reluctant_Linux_User Dec 10 '14 at 09:05
  • You can edit your question add this attempted code with formatting. – anubhava Dec 10 '14 at 09:46
  • I've managed to get this to work if I put it all in the one line and use "sed -e" but if I try "sed -i.bak" it never runs. – Reluctant_Linux_User Dec 11 '14 at 00:36
  • Probably your sed version is old and not supporting inline editing option. If it worked out then you mark the answer as accepted by clicking the tick mark on left side of my answer. – anubhava Dec 11 '14 at 03:06
1

At the moment I am passing it back and forth between a couple of temporary files

Writing and reading all those temp files is crazy, that's what pipes are for!

sed -e "s/9000000.0/${naerval}/" MC_NAMELIST_Pin14_Run3.IN | \
sed -e "s/8000000.0/${sig_aer}/" | \
sed -e "s/7000000.0/${d_aer}/" | etc.

But you can combine all the edits into one sed invocation with multiple scripts, preceding each one with -e:

sed -e "s/9000000.0/${naerval}/" -e "s/8000000.0/${sig_aer}/" -e "s/7000000.0/${d_aer}/" -e etc. etc. MC_NAMELIST_Pin14_Run3.IN > /tmp/NAMELIST.IN

Or as a single script with many commands, separated by semi-colons:

sed -e "s/9000000.0/${naerval}/;s/8000000.0/${sig_aer}/;s/7000000.0/${d_aer}/;..." MC_NAMELIST_Pin14_Run3.IN > /tmp/NAMELIST.IN
Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
0

Try something like:

sed -i.bak -e 's/9000000.0/${naerval}/' -e 's/8000000.0/${sig_aer}/' MC_NAMELIST_Pin14_Run3.IN 
SMA
  • 36,381
  • 8
  • 49
  • 73