열을 열로 복사 또는 반복

열을 열로 복사 또는 반복

awk '{print $1$1$1$1$1$1$1$1$1$1$1$1$1}'게시된 대로 원하는 출력을 얻기 위해 아래 출력을 파이프할 수 있습니다 .CodeGolf SE에서 알파벳 파도 인쇄.

열을 다른 열로 복사/반복하는 더 좋은 방법이 있습니까(수직의? ) bash 및/또는 기타 *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

답변1

첫째, 2개의 printfs + 1개의 에코를 단일 printf로 단순화할 수 있다고 생각합니다.

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

모든 것을 셸에 유지하려면 여기에 설명된 트릭을 사용할 수 있습니다.printf 명령을 사용하여 문자를 N 번 쓰세요, 즉.

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

아니면 좀 더 투명하게

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

순수 쉘을 사용하지 않을 경우, 떠오르는 모든 문자 쌍을 반복하는 데 사용할 수 있는 몇 가지 다른 기술이 있습니다.

  1. Perl의 곱셈 연산자 사용

    . . . | perl -lne 'print $_ x 13'
    
  2. sed 루프 사용

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

실제로 sed에서도 문자 일치를 수행할 수 있습니다.

$ printf \%b {A..Z} A \\n | 
    sed -E '/^Z/! s/(.)(.)/&\n\2/; 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

단일 sed 호출로 가능해야 합니다.

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

하지만 외부 GNU 확장에 의지하지 않고는 종료 조건을 제대로 얻을 수 없었습니다.

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

답변2

어떤 방식으로든 코드를 최적화하려고 하지 않고도(이것이 어려운 일입니다!) 다음을 수행할 수 있습니다.

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

그리고 나서 간단히

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

예를 들어

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

하나 있다많은그러나 다양한 최적화 방법이 있습니다.

관련 정보