ブレース展開での順列作成
ターミナル(コマンドライン)上で特定の文字列の組み合わせを作りたい時、一番最初に思いついたのがブレース展開を利用した下記でした。
1 2 3 |
# 例)1 3 3 7のすべてを使った順列を出したい echo {1,3,7}{1,3,7}{1,3,7}{1,3,7} | xargs -n 1 | grep 1 | grep -E 3.*3 | grep 7 | sort -u |
それぞれの処理は下記のような感じです。
1 2 3 4 5 6 7 8 9 10 11 12 |
#すべての組み合わせをブレース展開を使って出す echo {1,3,7}{1,3,7}{1,3,7}{1,3,7} #4つの数字出力ごとに縦にする xargs -n 1 # 1が1つ 3が2つ 7が1つ含まれている列だけに絞る grep 1 | grep -E 3.*3 | grep 7 # ソートしつつユニーク sort -u |
ただ、これだと数字が変わるたびに中括弧の中やgrepの条件をを書き換えなければいけないのでめんどうです。
初歩的コマンドだけで出せるのは利点ですが、いろいろ試すにはちょっとなぁという感じですね。
言語の力を借りて順列作成
調べてみたところ、PythonやRubyに順列を出力してくれる関数があるようなので使ってみました。
Python3
1 2 3 4 |
# python3 # ※無理やり1行にしないでファイルにしろよ、、、というツッコミは受け付けません python3 -c "import itertools;[print(''.join(i)) for i in list(itertools.permutations('1337'))]" | sort -u |
Ruby
1 2 3 4 5 6 |
#ruby # ※無理やり1行にしないでファイルにしろよ、、、というツッコミは受け付けません ruby -e '[1,3,3,7].permutation(4).each{|n| puts n.join}' OR ruby -e '[1,3,3,7].permutation(4).each{|n| n.each{|m| print m}; print "\n"}' | sort -u |
環境によってはもしかしたら若干コマンドいじらないといけないかもしれませんが、私のMacとLinuxの環境では一応動作しました。
これで突然順列が欲しくなっても大丈夫ですね。
最後に
それなりの短さでいい感じに書けましたね.
ただ、Pythonの方の処理は個人的にはあんまり好きではないですね,,,
処理の流れ的に、右から左に処理をしていくようにどうしても見えてしまうので直感的に分かりづらいです。
なのでおすすめはRubyですね。
おまけ
ちなみに、最近シェル芸を体系的に?勉強できる本(シェル・ワンライナー160本ノック)が出版されたのでやり始めました。
(まだ40本しか終わってないなんて口が裂けても言えない)
かなり基礎的な内容もやってくださるので技術力に自信がない方にもおすすめです。
ただし、全部読み切るのは結構大変そうなので興味のあるところをつまみ食いするのが一番良さそうだなぁという印象です。
シェル芸人になりたい方は是非やりましょう。
1日1問、半年以内に習得 シェル・ワンライナー160本ノック (Software Design plusシリーズ)
1日1問、半年以内に習得 シェル・ワンライナー160本ノック (Software Design plusシリーズ)
コメント