theFunnyEngineer
theFunnyEngineer

Reputation: 33

Replacing specific lines in multiple files using bash

I'm relatively new to bash scripting, having started out of the need to manage my simulations on supercomputers. I'm currently stuck on writing a script to change specific lines in my pbs files.

There's 2 stages to my problem. First, I need to replace a number of lines in a text file (another script), and overwrite that file for my later use. The rough idea is:

Replace lines 27, 28 and 29 of 'filename005' with 'text1=000', 'text2=005' and 'text3=010'

Next, I'd like to do that recursively for a set of text files with numbered suffixes, and the numbering influences the replaced text.

My code so far is:

#!/bin/bash
for ((i = 1; i < 10; i++))
    do
    let NUM=i*5
    let OLD=NUM-5
    let NOW=NUM
    let NEW=NUM+5

    let FILE=$(printf "filename%03g" $NUM)
    sed "27 c\text1=$OLD" $FILE
    sed "28 c\text2=$NOW" $FILE
    sed "29 c\text3=$NEW" $FILE
done

I know there are some errors in the last 4 lines of my code, and I'm still studying up on the proper way to implement sed. Appreciate any tips!

Thanks! CS

Upvotes: 3

Views: 1201

Answers (2)

theFunnyEngineer
theFunnyEngineer

Reputation: 33

Okay, I managed to get my code to work after finding out that for in-line replacement, I need to write it to a temporary file. So, with the recursive loop and multi-line replacement (and other small tweaks):

for ((i = 1; i < 10; i++ ))
    do
    let NUM=i*5
    let OLD=NUM-5
    let NOW=NUM
    let NEW=NUM+5

    FILE=`printf "filename%03g" $NUM`

    sed -e "27,29 c\
    OLD=$OLD\n\
    NOW=$NOW\n\
    NEW=$NEW" $FILE >temp.tmp && mv temp.tmp $FILE
done

Do let me know if there is a more elegant way to use sed in this context. Thanks again @Johnathan!

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 753695

Taking the first line of your specification:

Replace lines 27:29 of filename005, with text1=000; text2=005; text3=010

That becomes:

sed -e '27,29c\
text1=000\
text2=005\
text3=010' filename005

Rinse and repeat. The backslashes indicate to sed that the change continues. It's easier on yourself if your actual data lines do not need to end with backslashes.

You can play with:

seq 1 35 |
sed -e '27,29c\
text1=000\
text2=005\
text3=010'

to see what happens without risking damage to precious files. Given the specification lines, you could write a sed script to generate sed scripts from the specification (though I'd be tempted to use Perl or awk instead; indeed, I'd probably do the whole job in Perl).

Upvotes: 1

Related Questions