4

a. Have set of lines as given below.

cr_v8_sel0 : cross cp_v8_en, cp_sel0 {
   ignore_bins ig_v8_sel0 = binsof(cp_v8_en) && binsof(cp_sel0) intersect {[0:3],[5:$]}; 
}

b. I wanted to print the same set of lines multiple times with the decimal~string changed from sel0 to sel31.

c. For Eg: Note: sel0 is the lines is changed to sel1 and printed. And need from sel0 till sel31.

cr_v8_sel0 : cross cp_v8_en, cp_sel0 {
   ignore_bins ig_v8_sel0 = binsof(cp_v8_en) && binsof(cp_sel0) intersect {[0:3],[5:$]}; 
}
cr_v8_sel1 : cross cp_v8_en, cp_sel1 {
   ignore_bins ig_v8_sel0 = binsof(cp_v8_en) && binsof(cp_sel1) intersect {[0:3],[5:$]}; 
}

d. Can we do it in some for loop fashion to print them all ? rather than typing in hands ? using sed or awk or any script command ?

  • In your example, one of the instances of sel0 in the second group was left unchanged. Was that intentional? – John1024 Jul 9 '16 at 19:36
4

Try:

awk '{print; for (i=1;i<=31;i++) {x=$0; gsub(/sel0/, "sel" i, x); print x;}}' RS="" file

For example, and limited to 3 repetitions:

$ awk '{print; for (i=1;i<=3;i++) {x=$0; gsub(/sel0/, "sel" i, x); print x;}}' RS="" file
cr_v8_sel0 : cross cp_v8_en, cp_sel0 {
   ignore_bins ig_v8_sel0 = binsof(cp_v8_en) && binsof(cp_sel0) intersect {[0:3],[5:$]}; 
}
cr_v8_sel1 : cross cp_v8_en, cp_sel1 {
   ignore_bins ig_v8_sel1 = binsof(cp_v8_en) && binsof(cp_sel1) intersect {[0:3],[5:$]}; 
}
cr_v8_sel2 : cross cp_v8_en, cp_sel2 {
   ignore_bins ig_v8_sel2 = binsof(cp_v8_en) && binsof(cp_sel2) intersect {[0:3],[5:$]}; 
}
cr_v8_sel3 : cross cp_v8_en, cp_sel3 {
   ignore_bins ig_v8_sel3 = binsof(cp_v8_en) && binsof(cp_sel3) intersect {[0:3],[5:$]}; 
}

How it works

  • print

    This prints out the original version with sel0.

  • for (i=1;i<=31;i++) {x=$0; gsub(/sel0/, "sel" i, x); print x;

    This loops over i from 1 to 31, makes the substitutions and prints the result.

  • RS=""

    This tells awk to read an entire paragraph at a time. Since your source has no blank lines, this has the effect of reading your entire sources at once.

Multiline version

awk '
  {
     print
     for (i=1;i<=31;i++)
     {
       x=$0
       gsub(/sel0/, "sel" i, x)
       print x;
     }
   }
   ' RS="" file
  • 1
    That was freaking awesome ! Appreciate that timely response and it works great ! – Vimo Jul 9 '16 at 19:45
  • To simplify for (i=0;i<=31;i++) {gsub("sel[0-9]+", "sel" i); print;} – Costas Jul 10 '16 at 6:08
3

With a here document:

for i in {0..31}; do 
cat << EOF
cr_v8_sel${i} : cross cp_v8_en, cp_sel${i} {
   ignore_bins ig_v8_sel${i} = binsof(cp_v8_en) && binsof(cp_sel${i}) intersect {[0:3],[5:$]}; 
}
EOF
done

Note that if you use this method, you need to be a careful that there is nothing else in the here-document that might get expanded by the shell (in this case, things like {[0:3],[5:$]} look like they might be, but in fact aren't - at least not in bash). An essentially similar (but safer) approach using the envsubst command from GNU gettext can substitute only the desired index, as follows:

  1. create an environment variable i for the index

    export i
    
  2. create a template file with the desired index replaced by variable i

    $ cat template
    cr_v8_sel${i} : cross cp_v8_en, cp_sel${i} {
       ignore_bins ig_v8_sel${i} = binsof(cp_v8_en) && binsof(cp_sel${i}) intersect {[0:3],[5:$]};
    }
    
  3. loop over values of i substituting only the value of i

    for i in {0..31}; do envsubst '$i' < template; done
    
2

Make an input file sel.txt, (nothing fancy, only what the OP had with no changes), run a bash loop, and use sed in there to do the work:

echo "cr_v8_sel0 : cross cp_v8_en, cp_sel0 {
   ignore_bins ig_v8_sel0 = binsof(cp_v8_en) && binsof(cp_sel0) intersect {[0:3],[5:$]}; 
}" > sel.txt

for f in {0..31} ; do sed 's/sel0/sel'$f'/g' sel.txt ; done

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.