Linuxでファイルからランダム行を読み取る
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の機能を活用する
bashとzshのみを使用して戦略を作成することは、不明確で移植性が低いため、最善のアイデアではありませんが、教訓的な観点からは興味深いものです。
組み込みコマンドと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"
それ以外の場合は、perlとawkで行ったことに頼りましょう。
$ 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コマンドの使用やシェル固有のコマンドの使用など、さまざまな戦略を適用して、ファイルのランダムな行を読み取るさまざまな方法について説明しました。