将列复制或重复为列

将列复制或重复为列

我可以通过管道传递下面的输出以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 个 echo 简化为单个 printf:

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

如果你想将所有内容保留在 shell 中,你可以使用这里描述的技巧使用 printf 命令写入一个字符 N 次, 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

或者,更透明地

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

如果您不打算使用纯 shell,那么可以使用其他一些技术来重复想到的每个字母对:

  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

有一个很多不过,有多种优化方法。

相关内容