Bash コマンドで超巨大ファイルを開けるようにする
この記事は2022/12/01に作成されました。
エンジニアをやっているとバグの 1 つや 2 つ、いや、100 や 1,000 つ位は余裕で遭遇していることでしょう。
バグを発見したのが自身であれば発生条件の推測は容易です。
ですが、発見したのが同僚、または運悪くユーザーだったりする場合は原因を探るのに苦労するでしょう。
さて、そんな時に頼りになるのが各種ログですが、稼働率の高いサービスのログはギガバイト級になることも珍しくありません。
さっさとバグの原因を突き止めたいのに、その手がかりになりそうなログファイルが 60 G バイト位だったりするとちょっとした悲劇です。ソフトや環境にもよりますが、たいてい正常に閲覧できません。
今回は Bash コマンドを使用してそんな巨大テキストファイルへ立ち向かう方法の話です。
Linux 環境や Mac ユーザーの方々はそのままコマンドラインで対応可能ですが、Windows ユーザーの方は Git Bash を使用すると同じコマンドが使用できます。
インストールはこちらのリンクから Git ごとダウンロードしましょう: https://gitforwindows.org/
split でファイルを分割する
ファイルを指定サイズ、または指定行数ごとに区切って、それぞれをファイルとして保存する方法です。
一番単純ですが、一番容量を食う方法です。ディスク容量に余裕があればこれから試してみましょう。
色々なオプションがありますが、ぜひ覚えるべきオプションは以下二つです。
-l: 続けて指定された数値の行数ごとにファイルが作成されます。
-d: 新たに作成されるファイルの接頭辞がアルファベッドではなく数字になります。
例として、以下のようなコマンドを実行すると、hoge.txt 内、1,000 行ごとに x00, x01, x02 … といった名前のファイルがカレントディレクトリに作成されます。
split -l 10000 -d ./hoge,txt
head, tail コマンドで先頭 or 末尾●行だけ抜き出す
調べたい対象行が先頭、もしくは末尾に存在する場合は head, もしくは tail コマンドで楽に抜き出すことができます。
そのまま less コマンドなどに繋げるのもアリですが、新しいファイルとして抜き出し結果を保存すれば好きなエディタで閲覧することも可能です。
head の場合も tail の場合も -n の後に続けて数値を入力すると指定行数ぶんだけ結果を出力します。
そして > で連結して新しいファイル名を指定すれば、抜き出した行のみが記載されたテキストファイルが得られます。
下記の例は hoge.txt から先頭(head)、もしくは末尾(tail) から 1,000 行を抜き出し、new.txt として保存する例です。
head -n 1000 ./hoge.txt > new.txt
tail -n 1000 ./hoge.txt > new.txt
sed で指定範囲の行のみ抜き出す
sed を使用すれば指定範囲の行のみを取得できます。
以下は 100 行目から 200 行目までを抜き出して、new.txt として保存する例です。
sed -n 100,200p ./hoge.txt > new.txt
grep で特定のワードが含まれている or 含まれていない行のみ抜き出す
大抵のログファイルは一行に一つの情報が書かれていますが、 grep コマンドはこのようなテキストファイルの絞り込みとして最適です。
例えば、「2022-11」 というワードが含まれている行だけ抜き出したかったら以下のようにします。
grep 2022-11 ./hoge.txt
更に「Wed」が含まれている(恐らく水曜日の)行のみに絞り込むならパイプで連結も可能です。
grep 2022-11 ./hoge.txt | grep Wed
最後に、「 00:」が含まれていない行を除外して、new.txt として保存してみましょう。
grep 2022-11 ./hoge.txt | grep Wed | grep -v " 00:" > new.txt
このように、複雑な絞り込み条件もパイプを用いて grep を重ね掛けすれば、ある程度狙い撃ちした情報でフィルタリングが可能です。
sed で不要な文字列を削除する
先ほど使用した sed コマンドはどちらかというと正規表現で文字列置換をする事が多いコマンドです。
なので、ログファイルの中から不要な部分を除く、といった方法でログファイルの内容を軽減することが可能です。
以下のようにすると [] で囲まれた部分を根こそぎ削除します。
sed -r 's/[.*]//g' ./hoge.txt > new.txt
まとめ
サービスが沢山使われるのは素晴らしいことですが、そのぶん蓄積されるデータは膨大になり、対して我々の PC スペックは有限です。一般的なサイズのテキストデータでなければ、ソフトウェア側が対応していないのも致し方ないでしょう。
対して、Bash などのコマンドラインツールはそもそも「一般的なユーザーの一般的な用途」に対してのソフトウェアではなく、「使おうとする全てのユーザーに対する幅広い用途」に対してのソフトウェアと見ることができます。
コマンドラインは慣れないうちは使いづらいものですが、そのぶん「一般的でない」ようなタスクもあっさりこなせるポテンシャルを秘めているかもしれません。
いざというときのために慣れておくと、未来の自分から感謝されるかもしれませんよ。
プログラマー/N.Go