LoginSignup
2
1

More than 3 years have passed since last update.

「お好きなランダム文字列」生成コマンドを組んでみた

Last updated at Posted at 2019-04-13

こんにちは。久しぶりに投稿します。

なにがしたいのか

パスワード生成とか、何かと需要のあるランダム文字列を、コマンド1つでターンと出力できるようなモノを実装したかった。

結果

先に結果を共有します。
スクリーンショット 2019-04-13 23.54.12.png

使い方は単純で、
rndstrコマンドに必要に応じて以下のオプションを渡すだけ。
- -n 数字
- -a 英小文字
- -A 英大文字
- -m マイナス(「-」 <-ハイフンですよね...)
- -u アンダーバー(「_」)
- -L 20 長さ20の文字列を出力(省略すると長さ10)
- -C 10 10個の文字列を出力(省略すると1個)
このうち、naAのいずれかのオプションがないとエラーを吐きます。

ソースコードはコチラ

実装

まず、shell scriptを書く。

1.標準の長さと標準個数を変数で用意

#!/bin/sh

LEN=10
CNT=1

2.getoptsを用いてオプションを設定

test とか [ ~ ]で実装もできますが、今回は便利なコマンドを使います。

参考:UNIX & Linux コマンド・シェルスクリプトリファレンス 様

冒頭で挙げたオプションについてそれぞれフラグを設定しつつ、正規表現パターンに関する処理も行います。(パターンは後ほど使います。)
ちなみに引数付きのオプションは$OPT$OPTARGといった形で持ってこれます。

パターンを見ればわかりますが見間違いやすい文字を省いています。(数字の0と英字のo とか)


while getopts naAmuL:C: OPT
do
  case $OPT in
    "n" ) FLG_NUMBER="TRUE" ; PATTERN="${PATTERN}12345678" ;;
    "a" ) FLG_small="TRUE" ; PATTERN="${PATTERN}abcdefghijkmnpqrstuvwxyz" ;;
    "A" ) FLG_LARGE="TRUE" ; PATTERN="${PATTERN}ABCDEFGHIJKLMNPQRSTUVWXYZ" ;;
    "m" ) FLG_MINUS="TRUE" ; PATTERN="${PATTERN}\-" ;;
    "u" ) FLG_UBAR="TRUE" ; PATTERN="${PATTERN}_" ;;
    "L" ) FLG_LENGTH="TRUE" ; LEN=$OPTARG ;;
    "C" ) FLG_COUNT="TRUE" ; CNT=$OPTARG ;;
  esac
done

3.エラー処理

フラグを利用して、「数字も英字もナシなんて許さないヨ」を実装します。

if [ -z "$FLG_NUMBER" ] && [ -z "$FLG_small" ] && [ -z "$FLG_LARGE" ] ; then
  echo "下記を最低1つ指定してください。"
  echo "[-n] 数字"
  echo "[-a] 英小文字"
  echo "[-A] 英大文字"
else
  # ...
fi

4.色々縛りをかける

変数CONTAINに正規表現パターンを代入し、「数字指定したのに数字が含まれてない!」等を防止しています。

そして最後の1行で

  • cat /dev/urandom ... 乱数文字列を取得
  • tr -dc ${PATTERN} ... $PATTERN以外の文字を削除
    • Mac OSではLC_CTYPE=Cを付さないとエラーが起きます。
  • fold -w ${LEN} ... $LEN行ごとに改行
  • grep -i "[${CONTAIN}]" ... 「数字指定したのに数字が含まれてない!」防止
  • grep -e '^[12...YZ]' ... 先頭が記号以外
  • head -n ${CNT} ... 先頭$CNT行だけ取得

という一連の処理を行い、必要なランダム文字列を取得することができます。

if [ -z "$FLG_NUMBER" ] && [ -z "$FLG_small" ] && [ -z "$FLG_LARGE" ] ; then
  # ...
else
  if [ -n "$FLG_MINUS" ] && [ -n "$FLG_UBAR" ] ; then
    CONTAIN="\-_"
  elif [ -n "$FLG_UBAR" ] ; then
    CONTAIN="_"
  elif [ -n "$FLG_MINUS" ] ; then
    CONTAIN="\-"
  elif [ -n "$FLG_NUMBER" ] ; then
    CONTAIN="12345678"
  else
    CONTAIN="abcdefghijkmnpqrstuvwxyz"
  fi

  cat /dev/urandom | LC_CTYPE=C tr -dc ${PATTERN} | fold -w ${LEN} | grep -i "[${CONTAIN}]" | grep -e '^[12345678abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ]' | head -n ${CNT}
fi

次に、保存&bashrc等に登録。

保存先は、ホームディレクトリに自作コマンド専用のディレクトリを作ってまとめておくと何かと楽です。
(今回は~/cmds/rndstr.shに保存します。)

ここで重要なのが権限です。shファイルを作っても実行権限がないと動きません。

chmod +x ~/cmds/rndstr.sh

で付与しておきましょう。

次に.bashrc.zshrcなどにコマンドを登録します。

alias rndstr='~/cmds/rndstr.sh'

この1行を足します。

おしまい。

2
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1