perl 回転コマンドの作成

# まえがき

perl最近面白くて、いじくって遊んでいたら、楽しいコマンドができた。

# 参考文献

[順列列挙(再帰版)](https://qiita.com/satzz/items/2fbefff07df3cb052240)

# 環境

```bash
[sqlite💖ceacf3fb0808 (土 11月 02 03:25:11) ~/script_scratch/perl]$perl --version
perl --version

This is perl 5, version 30, subversion 0 (v5.30.0) built for x86_64-linux-thread

Copyright 1987-2019, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

[sqlite💖ceacf3fb0808 (土 11月 02 03:25:16) ~/script_scratch/perl]$bash --version
bash --version
GNU bash, バージョン 5.0.0(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
ライセンス GPLv3+: GNU GPL バージョン 3 またはそれ以降 <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
```

# スクリプト

コマンド置換の結果をダブルクォートで囲むのと囲まないので、挙動が変化するのは楽しい。

circleファンクション内の動き

**#1.** 標準入力より与えられた引数を空白スペース区切りの配列として取り込む。
**#2.** 取り込んだ配列を先頭要素と残りの要素配列に分類して設定する。
**#3.** 取り込んだ配列をカンマ区切りで出力。
**#4.** 残りの要素数分、繰り返し処理。
**#4-1.** 残りの要素配列の後ろに先頭要素を追加して、カンマ区切りで出力。
**#4-2.** 残りの要素配列の後ろに先頭要素を追加。
**#4-3.** 残りの要素配列から、先頭要素を取り出して、**#4.**へ戻る。

```bash
[sqlite💓ceacf3fb0808 (土 11月 02 03:14:00) ~/script_scratch/perl]$cat 回転.sh
#!/bin/bash

usage(){
  cat <<EOF
Usage:
\$echo {a..d} | ./回転.sh
a,b,c,d
b,c,d,a
c,d,a,b
d,a,b,c
\$echo {d..a} | ./回転.sh
d,c,b,a
c,b,a,d
b,a,d,c
a,d,c,b
\$echo {4..1} | ./回転.sh
4,3,2,1
3,2,1,4
2,1,4,3
1,4,3,2
\$echo {1..4} | ./回転.sh
1,2,3,4
2,3,4,1
3,4,1,2
4,1,2,3
\$./回転.sh {1..4}
1,2,3,4
2,3,4,1
3,4,1,2
4,1,2,3
\$./回転.sh {4..1}
4,3,2,1
3,2,1,4
2,1,4,3
1,4,3,2
\$./回転.sh {a..d}
a,b,c,d
b,c,d,a
c,d,a,b
d,a,b,c
\$./回転.sh {d..a}
d,c,b,a
c,b,a,d
b,a,d,c
a,d,c,b
\$cat src
a b c d
\$cat src | ./回転.sh
a,b,c,d
b,c,d,a
c,d,a,b
d,a,b,c
\$./回転.sh \$(cat src)
a,b,c,d
b,c,d,a
c,d,a,b
d,a,b,c
\$echo {e..h} >>src
\$cat src
a b c d
e f g h
$./回転.sh \$(cat src)
a,b,c,d,e,f,g,h
b,c,d,e,f,g,h,a
c,d,e,f,g,h,a,b
d,e,f,g,h,a,b,c
e,f,g,h,a,b,c,d
f,g,h,a,b,c,d,e
g,h,a,b,c,d,e,f
h,a,b,c,d,e,f,g
$./回転.sh "\$(cat src)"
a,b,c,d
b,c,d,a
c,d,a,b
d,a,b,c
e,f,g,h
f,g,h,e
g,h,e,f
h,e,f,g
\$cat src | ./回転.sh
a,b,c,d
b,c,d,a
c,d,a,b
d,a,b,c
e,f,g,h
f,g,h,e
g,h,e,f
h,e,f,g
EOF
}

circle(){
  script=$(cat <<EOF
  my @array=qw($@);
  my(\$first,@remain)=@array;
  print(join(",",@array),"\n");
  for(@remain){
    print(join(",",@remain,\$first),"\n");
    push(@remain,\$first);
    \$first=shift(@remain);
  }
EOF
  )
  echo -e perl -e "\x27""${script}""\x27" | bash
}

chk_args(){
  declare -a argv=()
  local argv=($@)
  local argc="${#argv[@]}"
  [ "${argc}" -le 1 ] && usage && exit 1
}

main(){
  local init_args="$(cat -)";
  chk_args "${init_args}"
  while read ln;do circle "${ln}";done <<<"${init_args}"
}

[ -p /dev/stdin ] && cat - | main
[ -p /dev/stdin ] || echo -ne "$@" | main
```

# 動作確認

コマンド置換の結果をダブルクォートで囲まない場合は、複数行の標準入力をインラインにしてコマンドに渡しているのに対して、囲む場合は複数行の標準入力を改行してコマンドに渡しているのが面白い。

```bash
[sqlite💓ceacf3fb0808 (土 11月 02 03:19:33) ~/script_scratch/perl]$cat src
a b c d
e f g h
[sqlite💓ceacf3fb0808 (土 11月 02 03:19:39) ~/script_scratch/perl]$./回転.sh $(cat src)
a,b,c,d,e,f,g,h
b,c,d,e,f,g,h,a
c,d,e,f,g,h,a,b
d,e,f,g,h,a,b,c
e,f,g,h,a,b,c,d
f,g,h,a,b,c,d,e
g,h,a,b,c,d,e,f
h,a,b,c,d,e,f,g
[sqlite💓ceacf3fb0808 (土 11月 02 03:19:42) ~/script_scratch/perl]$./回転.sh "$(cat src)"
a,b,c,d
b,c,d,a
c,d,a,b
d,a,b,c
e,f,g,h
f,g,h,e
g,h,e,f
h,e,f,g
[sqlite💓ceacf3fb0808 (土 11月 02 03:19:45) ~/script_scratch/perl]$./回転.sh "$(cat src|tac)"
e,f,g,h
f,g,h,e
g,h,e,f
h,e,f,g
a,b,c,d
b,c,d,a
c,d,a,b
d,a,b,c
[sqlite💓ceacf3fb0808 (土 11月 02 03:19:56) ~/script_scratch/perl]$./回転.sh "$(cat src|tac|rev)"
h,g,f,e
g,f,e,h
f,e,h,g
e,h,g,f
d,c,b,a
c,b,a,d
b,a,d,c
a,d,c,b
```

# 絵文字を交えて遊ぶ

きれいだ。

```bash
[sqlite💟ceacf3fb0808 (土 11月 02 03:27:31) ~/script_scratch/perl]$cat emoji
💠 💡 💢 💣 💤 💥 💦 💧
💨 💩 💪 💫 💬 💭 💮 💯
[sqlite💟ceacf3fb0808 (土 11月 02 03:27:44) ~/script_scratch/perl]$./回転.sh "$(cat emoji)"
💠,💡,💢,💣,💤,💥,💦,💧
💡,💢,💣,💤,💥,💦,💧,💠
💢,💣,💤,💥,💦,💧,💠,💡
💣,💤,💥,💦,💧,💠,💡,💢
💤,💥,💦,💧,💠,💡,💢,💣
💥,💦,💧,💠,💡,💢,💣,💤
💦,💧,💠,💡,💢,💣,💤,💥
💧,💠,💡,💢,💣,💤,💥,💦
💨,💩,💪,💫,💬,💭,💮,💯
💩,💪,💫,💬,💭,💮,💯,💨
💪,💫,💬,💭,💮,💯,💨,💩
💫,💬,💭,💮,💯,💨,💩,💪
💬,💭,💮,💯,💨,💩,💪,💫
💭,💮,💯,💨,💩,💪,💫,💬
💮,💯,💨,💩,💪,💫,💬,💭
💯,💨,💩,💪,💫,💬,💭,💮
[sqlite💟ceacf3fb0808 (土 11月 02 03:27:49) ~/script_scratch/perl]$./回転.sh $(cat emoji)
💠,💡,💢,💣,💤,💥,💦,💧,💨,💩,💪,💫,💬,💭,💮,💯
💡,💢,💣,💤,💥,💦,💧,💨,💩,💪,💫,💬,💭,💮,💯,💠
💢,💣,💤,💥,💦,💧,💨,💩,💪,💫,💬,💭,💮,💯,💠,💡
💣,💤,💥,💦,💧,💨,💩,💪,💫,💬,💭,💮,💯,💠,💡,💢
💤,💥,💦,💧,💨,💩,💪,💫,💬,💭,💮,💯,💠,💡,💢,💣
💥,💦,💧,💨,💩,💪,💫,💬,💭,💮,💯,💠,💡,💢,💣,💤
💦,💧,💨,💩,💪,💫,💬,💭,💮,💯,💠,💡,💢,💣,💤,💥
💧,💨,💩,💪,💫,💬,💭,💮,💯,💠,💡,💢,💣,💤,💥,💦
💨,💩,💪,💫,💬,💭,💮,💯,💠,💡,💢,💣,💤,💥,💦,💧
💩,💪,💫,💬,💭,💮,💯,💠,💡,💢,💣,💤,💥,💦,💧,💨
💪,💫,💬,💭,💮,💯,💠,💡,💢,💣,💤,💥,💦,💧,💨,💩
💫,💬,💭,💮,💯,💠,💡,💢,💣,💤,💥,💦,💧,💨,💩,💪
💬,💭,💮,💯,💠,💡,💢,💣,💤,💥,💦,💧,💨,💩,💪,💫
💭,💮,💯,💠,💡,💢,💣,💤,💥,💦,💧,💨,💩,💪,💫,💬
💮,💯,💠,💡,💢,💣,💤,💥,💦,💧,💨,💩,💪,💫,💬,💭
💯,💠,💡,💢,💣,💤,💥,💦,💧,💨,💩,💪,💫,💬,💭,💮
[sqlite💟ceacf3fb0808 (土 11月 02 03:27:54) ~/script_scratch/perl]$cat emoji | ./回転.sh
💠,💡,💢,💣,💤,💥,💦,💧
💡,💢,💣,💤,💥,💦,💧,💠
💢,💣,💤,💥,💦,💧,💠,💡
💣,💤,💥,💦,💧,💠,💡,💢
💤,💥,💦,💧,💠,💡,💢,💣
💥,💦,💧,💠,💡,💢,💣,💤
💦,💧,💠,💡,💢,💣,💤,💥
💧,💠,💡,💢,💣,💤,💥,💦
💨,💩,💪,💫,💬,💭,💮,💯
💩,💪,💫,💬,💭,💮,💯,💨
💪,💫,💬,💭,💮,💯,💨,💩
💫,💬,💭,💮,💯,💨,💩,💪
💬,💭,💮,💯,💨,💩,💪,💫
💭,💮,💯,💨,💩,💪,💫,💬
💮,💯,💨,💩,💪,💫,💬,💭
💯,💨,💩,💪,💫,💬,💭,💮
[sqlite💟ceacf3fb0808 (土 11月 02 03:28:05) ~/script_scratch/perl]$./回転.sh $(cat emoji|tac)
💨,💩,💪,💫,💬,💭,💮,💯,💠,💡,💢,💣,💤,💥,💦,💧
💩,💪,💫,💬,💭,💮,💯,💠,💡,💢,💣,💤,💥,💦,💧,💨
💪,💫,💬,💭,💮,💯,💠,💡,💢,💣,💤,💥,💦,💧,💨,💩
💫,💬,💭,💮,💯,💠,💡,💢,💣,💤,💥,💦,💧,💨,💩,💪
💬,💭,💮,💯,💠,💡,💢,💣,💤,💥,💦,💧,💨,💩,💪,💫
💭,💮,💯,💠,💡,💢,💣,💤,💥,💦,💧,💨,💩,💪,💫,💬
💮,💯,💠,💡,💢,💣,💤,💥,💦,💧,💨,💩,💪,💫,💬,💭
💯,💠,💡,💢,💣,💤,💥,💦,💧,💨,💩,💪,💫,💬,💭,💮
💠,💡,💢,💣,💤,💥,💦,💧,💨,💩,💪,💫,💬,💭,💮,💯
💡,💢,💣,💤,💥,💦,💧,💨,💩,💪,💫,💬,💭,💮,💯,💠
💢,💣,💤,💥,💦,💧,💨,💩,💪,💫,💬,💭,💮,💯,💠,💡
💣,💤,💥,💦,💧,💨,💩,💪,💫,💬,💭,💮,💯,💠,💡,💢
💤,💥,💦,💧,💨,💩,💪,💫,💬,💭,💮,💯,💠,💡,💢,💣
💥,💦,💧,💨,💩,💪,💫,💬,💭,💮,💯,💠,💡,💢,💣,💤
💦,💧,💨,💩,💪,💫,💬,💭,💮,💯,💠,💡,💢,💣,💤,💥
💧,💨,💩,💪,💫,💬,💭,💮,💯,💠,💡,💢,💣,💤,💥,💦
[sqlite💟ceacf3fb0808 (土 11月 02 03:28:21) ~/script_scratch/perl]$./回転.sh $(cat emoji|tac|rev)
💯,💮,💭,💬,💫,💪,💩,💨,💧,💦,💥,💤,💣,💢,💡,💠
💮,💭,💬,💫,💪,💩,💨,💧,💦,💥,💤,💣,💢,💡,💠,💯
💭,💬,💫,💪,💩,💨,💧,💦,💥,💤,💣,💢,💡,💠,💯,💮
💬,💫,💪,💩,💨,💧,💦,💥,💤,💣,💢,💡,💠,💯,💮,💭
💫,💪,💩,💨,💧,💦,💥,💤,💣,💢,💡,💠,💯,💮,💭,💬
💪,💩,💨,💧,💦,💥,💤,💣,💢,💡,💠,💯,💮,💭,💬,💫
💩,💨,💧,💦,💥,💤,💣,💢,💡,💠,💯,💮,💭,💬,💫,💪
💨,💧,💦,💥,💤,💣,💢,💡,💠,💯,💮,💭,💬,💫,💪,💩
💧,💦,💥,💤,💣,💢,💡,💠,💯,💮,💭,💬,💫,💪,💩,💨
💦,💥,💤,💣,💢,💡,💠,💯,💮,💭,💬,💫,💪,💩,💨,💧
💥,💤,💣,💢,💡,💠,💯,💮,💭,💬,💫,💪,💩,💨,💧,💦
💤,💣,💢,💡,💠,💯,💮,💭,💬,💫,💪,💩,💨,💧,💦,💥
💣,💢,💡,💠,💯,💮,💭,💬,💫,💪,💩,💨,💧,💦,💥,💤
💢,💡,💠,💯,💮,💭,💬,💫,💪,💩,💨,💧,💦,💥,💤,💣
💡,💠,💯,💮,💭,💬,💫,💪,💩,💨,💧,💦,💥,💤,💣,💢
💠,💯,💮,💭,💬,💫,💪,💩,💨,💧,💦,💥,💤,💣,💢,💡
```

# あとがき

テストデータ作成とかに役立つのかな。

```bash
$cat /dev/random | tr -dc a-z | fold -s5 | head -n10 | xargs -n5 | ./回転.sh
akblp,mwszw,naaqu,hemef,pydau
mwszw,naaqu,hemef,pydau,akblp
naaqu,hemef,pydau,akblp,mwszw
hemef,pydau,akblp,mwszw,naaqu
pydau,akblp,mwszw,naaqu,hemef
abquv,ijgkt,spdgd,kkjia,czdge
ijgkt,spdgd,kkjia,czdge,abquv
spdgd,kkjia,czdge,abquv,ijgkt
kkjia,czdge,abquv,ijgkt,spdgd
czdge,abquv,ijgkt,spdgd,kkjia
```

perl便利たのしい!

以上、ありがとうございました。