Fornax-A
Fornax-A

Reputation: 1032

Bash: nested for loop to iterativly change a paritular element in a matrix

I try to change in a file.txt formatted as the follow:

0.0 0.0 1.0 2.0 3.0
0.0 0.0 3.0 3.0 35.0 
...

only the second zeros in each lines: from 0.0 to some numbers.

I know that the sed command change elements but if I write something like that:

input=0 
  for f in {0..2}
  do   
  sed -i "1s/$input/$f/" file.txt
 input=$f
done

the sed command change the first zero in the file, changing it to:

1.0 0.0 1.0 2.0 3.0
1.0 0.0 3.0 3.0 35.0
...

But, instead, I would like:

0.0 0.1 1.0 2.0 3.0
0.0 0.1 3.0 3.0 35.0
...

So How can I specify where sed must change the number?

Upgrade:

I try to use sed command as guessed by sadasidha:

number=0.2
sed -r "s/^([0-9].[0-9]) ([0-9].[0-9])/\1 ${number}/" input.txt

but my request was a bit different, the idea was to make a loop in which I can increment the second element on the fourth line, for instance, 10 times, then the second element of the third line, then the second line and then the first one...as in a four loop as:

input=0
     for f in {0..10}
       for m in {0..10}
        for s in {0..10}
         for g in {0..10}
      do   
       change the second element on the fourth line 10 times,
     input=$f
    done
        change the second element on the third line 10 times,
     input=$m
    done
....

So i can have 11^4 different values of the elements in the second rows for each combination of numbers i put inside the do loop (i.e.: between 0,10).

Upvotes: 1

Views: 125

Answers (3)

mirmdasif
mirmdasif

Reputation: 6354

number=0.2
sed -r "s/^([0-9].[0-9]) ([0-9].[0-9])/\1 ${number}/" input.txt

Upvotes: 0

jaypal singh
jaypal singh

Reputation: 77105

This is a job for awk. By default awk splits of sequences of whitespaces ([[:space:]]+). Once awk reads the line, it splits the line on the default delimiter and assigns them to variables which can be referenced using $ and column number.

For your example:

$ cat file
0.0 0.0 1.0 2.0 3.0
0.0 0.0 3.0 3.0 35.0

$ awk '{$2=($2==0?0.1:$2)}1' file
0.0 0.1 1.0 2.0 3.0
0.0 0.1 3.0 3.0 35.0

We increment the value of second column using $2 and the 1 at the end allows us to print the line. You can also right it as:

$ awk '{$2=($2==0?0.1:$2); print}' file
0.0 0.1 1.0 2.0 3.0
0.0 0.1 3.0 3.0 35.0

Upvotes: 2

clt60
clt60

Reputation: 63922

easy with perl

perl -lanE '$F[1]=0.1 unless $F[1]+0; say "@F"' filename

for the next input

0.0 0.0 1.0 2.0 3.0
0.0 0.0 3.0 3.0 35.0 
0.0 0.9 3.0 3.0 35.0 

prints

0.0 0.1 1.0 2.0 3.0
0.0 0.1 3.0 3.0 35.0
0.0 0.9 3.0 3.0 35.0

Upvotes: 1

Related Questions