410gone.click

©2021 sumomo-99

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

更新日: 2021-04-11T08:28:59.598Z

Linux

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

shuf - generate random permutations

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

目次

  1. shufコマンドの使い方
  2. オプションなしの使用例
  3. コマンドラインで入力値を指定する
  4. 数字の順番をランダムに並び替える
  5. 指定した行数だけ表示する
  6. 入力に利用したファイルをシャッフルした結果で書き換える
  7. 1回利用した行を再利用する
  8. 行の区切りをNULに変更する

1. shufコマンドの使い方

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

fileを指定しない場合は、標準入力から読込みを行います。
option説明-e, --echoコマンドラインの引数を入力行とみなします。-i, --input-range=lo-hiloからhiまでの数値を入力とみなします。-n, --head-count=countcount行だけを表示します。デフォルトは全行の表示を行います。-o, --output=file結果を標準出力ではなくfileに出力します。--random-source=fileランダムデータのソースとしてfileを利用します。-r, --repeat1回選択された行も、繰り返し利用します。-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コマンドの使い方の紹介でした。