1. 概要

このチュートリアルでは、ファイルからテキストの行をランダムに選択するためのさまざまな戦略を見ていきます。

2. サンプルファイルの作成

始める前に、example_file.txtというファイルを作成しましょう。このファイルには10行の番号が付いています。

$ : > example_file.txt; seq 1 10 | xargs -I % echo line % | tee -a example_file.txt

3. shufを使用する

まず、shufコマンドを見てみましょう。 この場合、必要な行数を指定すると、shufはランダムな行を返します。

$ shuf -n 1 example_file.txt
line 2

4. awkを使用する

この問題に取り組むもう1つの方法は、awkを使用することです。

最初のアプローチは、がファイルの行数を知っている場合です。

$ n_lines=$(wc -l < example_file.txt); awk -v min=1 -v max=$n_lines '
BEGIN {
    srand()
    r_number=int( min + rand() * (max - min + 1) )
} 
NR == r_number' example_file.txt

それでは、コードを詳しく見てみましょう。

  • n_lines = $(wc -l ファイルから行数を取得します
  • -v min = 1 -v max = $ n_lines を使用して、ランダムな数値を取得する範囲に関する情報をawkスクリプトに渡します。
  • ここで、 r_number = int(min + rand()*(max – min + 1))は、渡された変数を使用して作成した範囲からランダムな数値を取得する場所です。
  • また、 NR == r_number を使用して、 awk に、現在のレジストリの番号が以前に作成した乱数と同じである場合は、デフォルトのawkを実行するように指示しています。 アクション:現在の行を出力します

2番目のアプローチは、ファイルの行数がわからない場合 、または他のコマンドの助けを借りずにawkのみを使用したい場合に役立ちます。

$ awk '
BEGIN{ srand() } 
rand() * NR < 1 { 
    line = $0 
} 
END { print line }' example_file.txt

srand 関数では、現在の日付と時刻をシードとして使用して、ランダムな数値を生成します。 そのため、コマンドを短期間に複数回実行すると同じ行が表示されます

5. perlを使用する

Perlを使用して、awk戦略に似たスクリプトを作成することもできます。

$ perl -e 'srand; rand($.) < 1 && ( $line = $_ ) while <>; print $line' example_file.txt

Perlドキュメントのファイルからランダムな行を選択するにはどうすればよいですか?のセクションに、このアルゴリズムの実装に関するさらに興味深い情報があります。

6. sedを使用する

それでは、sedコマンドを使用してみましょう。

$ rnd=$(( 1 + $RANDOM % $(wc -l < example_file.txt) )); sed -n "${rnd}p" example_file.txt

最後のコマンドラインを詳しく見てみましょう。

  • セクションで rnd = $((1 + $ RANDOM%$(wc -l 、1からファイルの行数までの範囲内からランダムな数値を選択します
  • sed -n“ $ {rnd} p” example_file.txt のセクションでは、sedに以前に取得したランダムな数と等しい数の行を出力するように指示します。

bashとzshには内部変数RANDOMとモジュロ演算子があるため、これを実現できます。

7. BashとZshの機能を活用する

bashzshのみを使用して戦略を作成することは、不明確で移植性が低いため、最善のアイデアではありませんが、教訓的な観点からは興味深いものです。

組み込みコマンドとbashおよびzshの内部変数のみを使用して、各アプローチを実装します。

ファイルの行数がわかっている場合:

$ n_lines=0
while read l
do 
    ((++n_lines))
done < example_file.txt
rnd_line=$(( 1 + RANDOM % n_lines))
n_line=1
while read line
do 
    (( n_line == rnd_line )) && break
    ((n_line++))
done < example_file.txt
echo "$line"

それ以外の場合は、perlawkで行ったことに頼りましょう。

$ n_line=1
while read crt_line
do 
    (( RANDOM % n_line < 1 )) && line="$crt_line"
    ((++n_line))
done < example_file.txt
echo "$line"

コマンドラインでコードを実行するだけでなく、実行可能ファイルとして実行するファイルにコードを保存することもできます。

8. 結論

この記事では、標準のLinuxコマンドの使用やシェル固有のコマンドの使用など、さまざまな戦略を適用して、ファイルのランダムな行を読み取るさまざまな方法について説明しました。