バナー芸人衆
TwitterとGistに投稿したが、せっかくなので忘れないうちにブログ記事にしておく。おとといに「符号化処理芸人衆」というタイトルで記事を書いたが、その中で@grethrenさんよりbannerコマンドについて教えてもらった。そういえばそんなコマンドあったね。
ちなみに、あのyesのやつですが、作り方があります。文字を地道に探したのではなく、作成も #シェル芸 でやりました。
— ぐれさん (@grethlen) 2016年9月22日
bannerコマンドというのがあってですね。。
> @papiron pic.twitter.com/sWFpUBLVUm
BSDのbannerコマンド
ところでこのbannerコマンド、MacやFreeBSDなどのBSDなシステムに付属してるものは、なかなかカッチョエエのを出力してくれる。しかし文字が右に90度回転してて、縦に流れる。こんな感じだ。
-w
オプションの後の数字は横幅の文字列長で、指定無しだとデフォルトが幅132のやたらとデカくて高精細なのが出てくる。
$ banner -w 30 Go ##### ############# ################# ### ## # # # # # # ## ## ######### #### ###### #### ######### ## ## # # # ## ## ## ######### ####
回転芸
じゃあこれを90度回転させて横に並べて出力すればよかやんね?ということでシェル芸ワンライナーをやってみたよ。
まずはawkで横幅が30文字になるまで右側を空白で埋める。出力結果が分かりにくいのでcat -e
で行末に$
マークを出力している。
$ banner -w 30 Go | awk '{printf $0;if(length<30)for(i=length;30-i>0;i++){printf " "}print ""}' | cat -e ##### $ ############# $ ################# $ ### ## $ # # $ # # $ # # $ ## ## $ ######### #### $ ###### $ #### $ ######### $ ## ## $ # # $ # ## $ ## ## $ ######### $ #### $
最初は上記のようにやっていたが、Twitterで@ebanさんからawkのprintf()
関数でフォーマットを"%-30s\n"
と指定すれば良いことに気が付いた。
Ubuntuで
— eban (@eban) 2016年9月24日
% printerbanner -w 40 Hage | awk '{printf "%-40s\n", $0}' | sed 's/./&\t/g' | rs -T -c -C | tr -d '\t' | tac | awk NF#シェル芸
ということで下記のように簡単になった。
$ banner -w 30 'Go' | awk '{printf "%-30s\n",$0}' | cat -e ##### $ ############# $ ################# $ ### ## $ # # $ # # $ # # $ ## ## $ ######### #### $ ###### $ #### $ ######### $ ## ## $ # # $ # ## $ ## ## $ ######### $ #### $
次にtrコマンドで#
を+
に、空白を-
へと変換する。
$ banner -w 30 'Go' | awk '{printf "%-30s\n",$0}' | tr '# ' '+-' ---------------+++++---------- -----------+++++++++++++------ ---------+++++++++++++++++---- --------+++--------------++--- --------+------------------+-- -------+-------------------+-- --------+------------------+-- --------++---------------++--- ---------+++++++++------++++-- ------------++++++------------ -----------++++--------------- ---------+++++++++------------ --------++-------++----------- -------+-----------+---------- -------+----------++---------- --------++-------++----------- ---------+++++++++------------ -----------++++---------------
ここからawkを使って行列入替処理を行う。処理自体は地道にやっているだけだが、FS=
を使うと1文字ずつフィールド分割してくれて楽だ。
$ banner -w 30 'Go' | awk '{printf "%-30s\n",$0}' | tr '# ' '+-' | awk '{for(i=1;i<=NF;i++)a[NR,i]=$i}END{for(j=1;j<=NF;j++){for(i=1;i<=NR;i++){printf a[i,j]}print ""}}' FS= ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ -----+-------++--- ---++-++----+--+-- --++---++--++--++- --++----+--+----+- -++-----+-++----++ -++-----++++----++ -++-----++++----++ -++-----++++----++ +++-----++-+----+- +++-----++-+----+- +++-----++-++--++- +++---------+-++-- +++----------++--- -++--------------- -++--------------- -++--------------- -++--------------- --+-----+--------- --++---++--------- ---+---++--------- ----+++-+--------- ------------------ ------------------
上下逆さまなのでtail -r
を使って上下逆転させる。tr
で元のバナーに戻して、更に行末の余計な空白をsed
で削除で完成。
$ banner -w 30 'Go' | awk '{printf "%-30s\n",$0}' | tr '# ' '+-' | awk '{for(i=1;i<=NF;i++)a[NR,i]=$i}END{for(j=1;j<=NF;j++){for(i=1;i<=NR;i++){printf a[i,j]}print ""}}' FS= | tail -r | tr '+-' '# ' | sed 's/ *$//' ### # # ## ## ## # # ## ## ## ## ### ## ### # ## ### ## ## ## ### ## # # ### ## # # ## #### ## ## #### ## ## #### ## ## # ## ## ## # # # ## ## ## ## ## ## # # # ##
ちなみにTukubaiのtateyoko
コマンドを使うと、簡単に行列入替処理が出来るぞ。また上記の@ebanさんのようにrs
コマンドを使う手もある。
$ banner -w 30 'Go' | awk '{printf "%-30s\n",$0}' | tr '# ' '+-' | sed 's/./& /g' | tateyoko - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - + + - - - - - - + + - + + - - - - + - - + - - - - + + - - - + + - - + + - - + + - - - + + - - - - + - - + - - - - + - - + + - - - - - + - + + - - - - + + - + + - - - - - + + + + - - - - + + - + + - - - - - + + + + - - - - + + - + + - - - - - + + + + - - - - + + + + + - - - - - + + - + - - - - + - + + + - - - - - + + - + - - - - + - + + + - - - - - + + - + + - - + + - + + + - - - - - - - - - + - + + - - + + + - - - - - - - - - - + + - - - - + + - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - + - - - - - + - - - - - - - - - - - + + - - - + + - - - - - - - - - - - - + - - - + + - - - - - - - - - - - - - + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Linuxでもやりたい
Linuxで出来ないのか?と思ってたら@ebanさんより援護射撃が。UbuntuやDebianだとbsdmainutils
というパッケージの中にprinterbanner
というコマンド名でBSDのbanner
コマンドが移植されているらしい。
printbannerはbsdmainutilsパッケージ
— eban (@eban) 2016年9月24日
Togetterまとめ
ということで、このネタから派生したTwitterのTLを@grethrenさんがTogetterでまとめてくれた。仕事早!ちなみにこのブログ記事を書いた後も、バナー出力に関するいろいろな情報や案が出てきて、想像斜め以上に進化をしていた・・・
シェルスクリプト化
ついでに上記のワンライナーをシェルスクリプト化作ったのでGistに設置。少し修正した。よかったらお使いあれ。UbuntuやDebianなどのLinuxでは、bsdmainutils
というパッケージを入れて、シェルスクリプト12行目banner
をprinterbanner
に書き換えればオケ!もう一つ27行目のtail -r
をtac
に書き換えること。
$ coolbanner 'Hey Siri' #### #### ##### ## ## # ## ## ## # # ## ## # # ## ## ## ## # ## ## ## ## # # # ## ## # ## ## ## ######### ## ### ## ##### ###### # ### ## ## # ## ## # ##### ## ## ### ## ## ## ## ## ## # ##### ## ### ## ## ## ## # ## ## ### ## ## ## ## ## ## # # ## # ### ## ## ## ## ## ## ## # ## # ## ## ## ## ## ## ####### ## # ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## # ## ## ## ## ## ## ## ## ## # ## ## # ## ## ## ## ## # # ### ## ## ## ## #### #### ## # # ### ###### ### # # # ### ###