[Linux] 入力行をランダムに入れ替えるshufコマンドの使い方

shufコマンドは入力した行をランダムに入れ替えます。

shuf – generate random permutations

shufマンドはGNU Coreutilsに含まれています。ここでは、shufコマンドの基本的な使い方を紹介します。
※以降の実行例は、Ubuntu17.10で確認しています。

1. shufコマンドの使い方

shuf [option]... [file]
shuf -e [option]... [arg]...
shuf -i LO-HI [option]...

fileを指定しない場合は、標準入力から読込みを行います。

option 説明
-e, --echo コマンドラインの引数を入力行とみなします。
-i, --input-range=lo-hi loからhiまでの数値を入力とみなします。
-n, --head-count=count count行だけを表示します。デフォルトは全行の表示を行います。
-o, --output=file 結果を標準出力ではなくfileに出力します。
--random-source=file ランダムデータのソースとしてfileを利用します。
-r, --repeat 1回選択された行も、繰り返し利用します。
-z, --zero-terminated 行の区切りをNULとします。
--help ヘルプを表示します。
--version バージョンを表示します。

2. オプションなしの使用例

shufコマンドをオプションなしで使用すると、全ての入力行をシャッフルして表示します。

$ cat shuf1.txt  #元のテキスト
1行目です。
2行目です。
3行目です。
4行目です。
5行目です。
$ shuf shuf1.txt  #シャッフル1回目
2行目です。
1行目です。
3行目です。
4行目です。
5行目です。
$ shuf shuf1.txt  #シャッフル2回目
3行目です。
1行目です。
5行目です。
4行目です。
2行目です。

3. コマンドラインで入力値を指定する

コマンドライン(引数)で入力を指定するには’-e‘オプションを利用します。

$ shuf -e aa bb cc dd ee
cc
dd
bb
aa
ee

4. 数字の順番をランダムに並び替える

任意の数値の順列をランダムに並び替えるには’-i‘オプションを利用します。

$ shuf -i 1-5  #1から5までの数値をシャッフルする
1
5
2
3
4

5. 指定した行数だけ表示する

-n‘オプションを利用することで、出力する行数を限定することができます。

$ shuf -n2 shuf1.txt  #2行だけ出力する
5行目です。
3行目です。

6. 入力に利用したファイルをシャッフルした結果で書き換える

入力に利用したファイルをシャッフルした結果で上書きを行うには、’-o‘オプションを利用します。
読込みと書込みのファイルが同じになり、読込みと書き出しの競合や不整合が起こる可能性があります。安全に書き出しを行うために、’-o‘で出力するファイルを開く前に全ての入力を読み込む必要があります。

$ cat shuf1.txt | shuf -o shuf1.txt  #パイプで入力内容を全て引き渡す
$ cat shuf1.txt
2行目です。
3行目です。
5行目です。
4行目です。
1行目です。
$ shuf -o shuf1.txt < shuf1.txt  #リダイレクトで入力内容を引き渡す
$ cat shuf1.txt
1行目です。
2行目です。
4行目です。
5行目です。
3行目です。

7. 1回利用した行を再利用する

じゃんけんを10回繰り返すなど、入力行を再利用したい場合は'-r'オプションを利用します。

$ shuf -n10 -r -e グー チョキ パー  #じゃんけんを10回おこなう
グー
グー
チョキ
チョキ
グー
チョキ
パー
グー
パー
チョキ

'-r'オプションを利用したときに'-n'オプションで回数を指定しないと無限ループになりますので注意してください。

8. 行の区切りをNULに変更する

shufコマンドの入力行の区切りは改行コードです。'-z'オプションを利用することで、行の区切りをNULに変更することができます。このオプションは、'find -print0'コマンド等で区切りをNULに変更している場合などで利用できます。

$ find /etc/logrotate.d -type f -print0 | shuf -z  #1回目
/etc/logrotate.d/apt/etc/logrotate.d/netdata/etc/logrotate.d/lxd/etc/logrotate.d/psaccu_atop/etc/logrotate.d/nginx/etc/logrotate.d/apport/etc/logrotate.d/psaccs_atop/etc/logrotate.d/unattended-upgrades/etc/logrotate.d/dpkg/etc/logrotate.d/rsyslog
$
$ find /etc/logrotate.d -type f -print0 | shuf -z  #2回目
/etc/logrotate.d/apport/etc/logrotate.d/psaccu_atop/etc/logrotate.d/lxd/etc/logrotate.d/nginx/etc/logrotate.d/dpkg/etc/logrotate.d/rsyslog/etc/logrotate.d/psaccs_atop/etc/logrotate.d/apt/etc/logrotate.d/netdata/etc/logrotate.d/unattended-upgrades

 
以上、入力行をランダムに入れ替えるshufコマンドの使い方の紹介でした。