DavidC.
DavidC.

Reputation: 677

In bash: a "sed" command of a $VARIABLE inside a for loop

I have a file that has these lines:

s17 line linewidth 1.0
s18 line linewidth 1.0
.
.
.
s28 line linewidth 1.0

I would like to replace these lines by:

 s17 line linewidth 2.0
 s18 line linewidth 2.0
 .
 .
 .
 s28 line linewidth 2.0

I have written this code in bash:

 #!/bin/bash
 for VARIABLE in {17..28}
 do
   sed 's/s${VARIABLE} line linewidth 1\.0/s${VARIABLE} line linewidth 2\.0/g' ./band-structure-calcite.agr
 done

Then I run the code by making bash change.sh > changed.txt but the file changed.txt does not contain these modifications.

I would appreciate very much if you help me and explain me the syntax of your code answers as I am learning bash

Upvotes: 0

Views: 651

Answers (3)

John Bollinger
John Bollinger

Reputation: 180351

Replace the loop with a regular expression in the address part of the sed command:

'/^s\(\(1[7-9]\)\|\(2[0-8]\)\)\s/ s/1\.0$/2.0/' ./band-structure-calcite.agr

The regular expression (/^s\(\(1[7-9]\)\|\(2[0-8]\)\)\s/) matches lines beginning with s17, s18, ... or s28, followed by a space or tab, and sed applies the following s/1\.0$/2.0/ command only to those lines. Other lines pass through unchanged. The whole file is read through exactly once, and the output contains one output line per input line, unlike your original.

Upvotes: 1

choroba
choroba

Reputation: 241918

Rather than running sed several times, generate a sed script in the loop and run it once:

for n in {17..28} ; do
    echo "s/s$n line linewidth 1\.0/s$n line linewidth 2.0/g"
done | sed -f- ./band-structure-calcite.agr > changed.txt

Upvotes: 2

Walter A
Walter A

Reputation: 20012

Make a regular expression with your numbers:

allnr=""
for nr in {17..28}
do
    allnr+="${nr}|"
done
# Debug: echo "allnr=${allnr%|}"
sed -r 's/s('"${allnr%|}"') line linewidth 1\.0/s\1 line linewidth 2.0/g' ./band-structure-calcite.agr

Upvotes: 1

Related Questions