Como imprimir as mesmas linhas várias vezes com variáveis alteradas usando Sed / Awk / anything?

4

a. Tenha um conjunto de linhas como indicado abaixo.

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. Eu queria imprimir o mesmo conjunto de linhas várias vezes com a string decimal ~ alterada de sel0 para sel31.

c. Por exemplo: Nota: sel0 é que as linhas são alteradas para sel1 e impressas. E precisa de sel0 até 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. Podemos fazê-lo de alguma maneira para imprimir todos eles? em vez de digitar as mãos? usando sed ou awk ou qualquer comando de script?

    
por Vimo 09.07.2016 / 21:25

3 respostas

4

Tente:

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

Por exemplo, e limitado a 3 repetições:

$ 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:$]}; 
}

Como funciona

  • print

    Isto imprime a versão original com sel0 .

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

    Isso faz um loop de i de 1 a 31, faz as substituições e imprime o resultado.

  • RS=""

    Isto diz ao awk para ler um parágrafo inteiro de cada vez. Como sua fonte não tem linhas em branco, isso tem o efeito de ler suas fontes inteiras de uma só vez.

Versão multilinha

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

Com um documento aqui:

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

Observe que, se você usar esse método, será necessário ter cuidado para que não haja mais nada no documento here que possa ser expandido pelo shell (nesse caso, coisas como {[0:3],[5:$]} parecem ser, mas na verdade não são - pelo menos não no bash). Uma abordagem essencialmente similar (mas mais segura) usando o comando envsubst do GNU gettext pode substituir somente o índice desejado, como segue:

  1. crie uma variável de ambiente i para o índice

    export i
    
  2. crie um arquivo de modelo com o índice desejado substituído pela variável 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. repetir os valores de i substituindo somente o valor de i

    for i in {0..31}; do envsubst '$i' < template; done
    
por 09.07.2016 / 22:12
2

Crie um arquivo de entrada sel.txt , (nada sofisticado, somente o que o OP tinha sem alterações), execute um bash loop e use sed para fazer o trabalho :

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
    
por 10.07.2016 / 05:00