Copie ou repita colunas como colunas

0

Eu poderia canalizar a saída abaixo para awk '{print $1$1$1$1$1$1$1$1$1$1$1$1$1}' para obter a saída desejada, conforme publicado na onda do alfabeto de impressão no CodeGolf SE .

Existe uma maneira melhor de copiar / repetir colunas como outra coluna ( verticalmente ?) usando o bash e / ou outros utilitários * nix?

for i in {0..25}; do 
  printf \$( printf '%03o' $((i+65)) );
  printf \$( printf '%03o' $((-~i%26+65)) ); 
  echo; 
done

AB
BC
CD
DE
EF
FG
GH
HI
IJ
JK
KL
LM
MN
NO
OP
PQ
QR
RS
ST
TU
UV
VW
WX
XY
YZ
ZA
    
por KM. 21.08.2016 / 16:44

2 respostas

2

Primeiro de tudo, você poderia simplificar seus 2 printfs + 1 eco para um único printf, eu acho:

for i in {0..25}; do 
  printf '%b%b\n' \$( printf '%03o' $((i+65)) ) \$( printf '%03o' $((-~i%26+65)) )
done

Se você quiser manter tudo no shell, use o truque descrito aqui Escrevendo um caractere N vezes usando o comando printf , ie

for i in {0..25}; do 
  printf "$(printf '%b%b' \$( printf '%03o' $((i+65)) ) \$( printf '%03o' $((-~i%26+65)) ))%.0s" {1..13}
  printf \n
done

ou, de forma mais transparente

for i in {0..25}; do 
  printf -v xy '%b%b' \$( printf '%03o' $((i+65)) ) \$( printf '%03o' $((-~i%26+65)) )
  printf "${xy}%.0s" {1..13}
  printf \n
done

Se você não está usando shell puro, algumas outras técnicas para reduplicar cada par de letras que vem à mente são

  1. usando o operador de multiplicação do perl

    . . . | perl -lne 'print $_ x 13'
    
  2. usando um loop sed

    . . . | sed -E ':a; /.{26}/! s/../&&/; ta'
    

Na verdade, você também poderia fazer o emparelhamento de letras em sed

$ printf \%b {A..Z} A \n | 
    sed -E '/^Z/! s/(.)(.)/&\n/; P;D; b' | sed -E ':a; /.{26,}/! s/../&&/; ta'
ABABABABABABABABABABABABAB
BCBCBCBCBCBCBCBCBCBCBCBCBC
CDCDCDCDCDCDCDCDCDCDCDCDCD
DEDEDEDEDEDEDEDEDEDEDEDEDE
EFEFEFEFEFEFEFEFEFEFEFEFEF
FGFGFGFGFGFGFGFGFGFGFGFGFG
GHGHGHGHGHGHGHGHGHGHGHGHGH
HIHIHIHIHIHIHIHIHIHIHIHIHI
IJIJIJIJIJIJIJIJIJIJIJIJIJ
JKJKJKJKJKJKJKJKJKJKJKJKJK
KLKLKLKLKLKLKLKLKLKLKLKLKL
LMLMLMLMLMLMLMLMLMLMLMLMLM
MNMNMNMNMNMNMNMNMNMNMNMNMN
NONONONONONONONONONONONONO
OPOPOPOPOPOPOPOPOPOPOPOPOP
PQPQPQPQPQPQPQPQPQPQPQPQPQ
QRQRQRQRQRQRQRQRQRQRQRQRQR
RSRSRSRSRSRSRSRSRSRSRSRSRS
STSTSTSTSTSTSTSTSTSTSTSTST
TUTUTUTUTUTUTUTUTUTUTUTUTU
UVUVUVUVUVUVUVUVUVUVUVUVUV
VWVWVWVWVWVWVWVWVWVWVWVWVW
WXWXWXWXWXWXWXWXWXWXWXWXWX
XYXYXYXYXYXYXYXYXYXYXYXYXY
YZYZYZYZYZYZYZYZYZYZYZYZYZ
ZAZAZAZAZAZAZAZAZAZAZAZAZA

Deve ser possível em uma única chamada de sed, algo como

printf \%b {A..Z} A \n | 
  sed -E ':1; /^Z/! s/(.)(.)/&\n/; :2; /.{26}\n/! s/../&&/; t2; P;D; b1'

mas não consigo obter a condição de finalização correta sem recorrer a extensões exóticas do GNU

printf \%b {A..Z} A \n |  
  sed -E ":1; /^Z/! s/(.)(.)/&\n/; :2; /.{26}(\n|\')/M! s/../&&/; t2; P;D; b1"
    
por 22.08.2016 / 04:18
1

Sem tentar otimizar seu código de forma alguma (esse é o desafio!), você pode fazer

x=$(printf ..statement1..)
y=$(printf ..statement2..)

e depois simplesmente

echo "$x$y$x$y$x$y$x$y$x$y...."

por exemplo

for i in {0..25}; do 
  x=$(printf \$( printf '%03o' $((i+65)) ))
  y=$(printf \$( printf '%03o' $((-~i%26+65)) )) 
  echo "$x$y$x$y$x$y$x$y"
done

Há um lote de maneiras de otimizar isso.

    
por 21.08.2016 / 16:59

Tags