user3319356
user3319356

Reputation: 173

While loop with nested for loop

I need help with bash script. So I have input data as

CellIden="461"
CellIden="465"
CellIden="468"
CellIden="462"
CellIden="466"
CellIden="469"
CellIden="463"
CellIden="467"
CellIden="460"

and I have created while loop

cat FolderCell2 | while read line ;
do
echo $line | sed -e 's/cellIden/Cell/g'
done > FolderCell3

so this will read each line and replace strings, but I need two more loops in this while script :

for (( i = 1; i <=$SEC_NUM ; i++ ))
do
for (( j = 1 ; j <=$Cell_Num ; j++ ))
do
sed -e 's/Cell/Cell$i$j/g'
done
done > File

the ouput shold be like this

Cell11="461"
Cell12="465"
Cell13="468"
Cell21="462"
Cell22="466"
Cell23="469"
Cell31="463"
Cell32="467"
Cell33="460"

Variables $SEC_NUM and $Cell_Num are sometimes different. So I don't know how to combine this two codes, while loop together with two for loop to get ouput as this above.

Upvotes: 1

Views: 151

Answers (5)

BMW
BMW

Reputation: 45243

this is something that converts 1D array data to 2D array. Only one of (SEC_NUM or Cell_Num) is required in fact.

awk -v SEC_NUM=3 '{i=(NR-1)%SEC_NUM+1;j=int((NR-1)/SEC_NUM)+1;sub(/CellIden/,"Cell" j i)}1' file

Cell11="461"
Cell12="465"
Cell13="468"
Cell21="462"
Cell22="466"
Cell23="469"
Cell31="463"
Cell32="467"
Cell33="460"

awk -v SEC_NUM=4 '{i=(NR-1)%SEC_NUM+1;j=int((NR-1)/SEC_NUM)+1;sub(/CellIden/,"Cell" j i)}1' file
Cell11="461"
Cell12="465"
Cell13="468"
Cell14="462"
Cell21="466"
Cell22="469"
Cell23="463"
Cell24="467"
Cell31="460"

Upvotes: 1

anishsane
anishsane

Reputation: 20980

Another approach:

i=0
while read -r line;
do
    j=$(bc <<< "obase=$Cell_Num; $i" | xargs printf "%02d" | tr '[0-8]' '[1-9]')
    sed "s/CellIden=/Cell$j=/" <<< "$line"
    ((i++))
done < FolderCell2 > file.out

Effectively, encode the number with base 3 ($Cell_Num),
then print with leading zeros.
Finally, since your numbering starts with 1, not 0, replace all 0-8 with 1-9.

Upvotes: 1

itzhaki
itzhaki

Reputation: 840

When parsing line-by-line I find it more convenient to work with an AWK script.

Consider the following code:

#!/bin/awk

BEGIN{
        i=1;
        j=1;
}

{
        split($0,arr,"\"");
        print "Cell" i j "=\"" arr[2] "\""
        j++;
        if (j > CELL_NUM){
                j=1;
                i++;
        }
        if (i > SEC_NUM){
                i=1;
        }
}

END{

}

Then assuming the script is test.awk and the input file is 1.txt, run this way:

awk -vCELL_NUM=3 -vSEC_NUM=3 -f test.awk 1.txt

Getting your wanted output:

Cell11="461"
Cell12="465"
Cell13="468"
Cell21="462"
Cell22="466"
Cell23="469"
Cell31="463"
Cell32="467"
Cell33="460"

Upvotes: 2

Fritz G. Mehner
Fritz G. Mehner

Reputation: 17188

A solution:

SEC_NUM=3
CellNum=3

i=0
j=0

while read line ; do
  echo  "${line/CellIden/Cell$((i+1))$((j+1))}"
  ((j=(j+1)%CellNum))
  [ $j -eq 0 ] && ((i=(i+1)%SEC_NUM))
done < "$infile" > "$outfile"

The variable j will be incremented in every loop cycle. The variable i will be incremented in every SEC_NUM-th cycle. The replacement is done with a parameter substitution to avoid sed.

For

SEC_NUM=3
CellNum=4

the output is

Cell11="461"
Cell12="465"
Cell13="468"
Cell14="462"
Cell21="466"
Cell22="469"
Cell23="463"
Cell24="467"
Cell31="460"

Upvotes: 1

anubhava
anubhava

Reputation: 785156

Something like this should work:

i=1
while read -r line;
do
    j=1
    sed "s/CellIden=/Cell$i$j=/" <<< "$line"
    for ((j=2; j<=$Cell_Num; j++)); do
        read -r line
        sed "s/CellIden=/Cell$i$j=/" <<< "$line"
    done
    ((i++))
done < FolderCell2 > file.out

Upvotes: 1

Related Questions