LoginSignup
0
0

More than 5 years have passed since last update.

検索対象文字列に一致した行と前の行も出力するプログラム

Last updated at Posted at 2018-08-24

「任意の文字列や行をハイライトするツールをGo言語で作成してみた」grepコマンドの-Bオプションと似た動作をするプログラムが必要となったのでその作り方のメモを残しておく。

何が必要になったか

以下のようなfile.txtが存在した場合に

file.txt
message1
Hello World.
message2
hello world.
message3
HELLO WORLD.

一致した行とその前の2行も出力するgrepコマンドを実行した場合、以下の結果が得られる

$ grep -B 2 hello file.txt
Hello World.
message2
hello world.

これと似た動作をするプログラムが必要となった。

作成した関数

上記の動作と似た動作をする関数は以下の通り。

// pattern 検索対象文字列
// lines   ファイルを一行ずつ読み込んだ結果が流れてくるチャンネル
func grepBefore(pattern, lines chan string){
    n := 2 // 保持しておく行数
    buf := []string{} // 保持用のスライス
    for line := range lines {
        // 指定保持数を超えたら一番前の行を保持用スライスから削除
        if len(buf) > n {
            buf = buf[1:]
        }
        buf = append(buf, line)

        // 現在の行にpatternが含まれているならば、出力処理を行う
        if strings.Contains(line, pattern) {
            for _, l := range buf {
                fmt.Println(l)
            }
            // bufを空にする
            buf = buf[:0]
        }
    }
}

動作順序

  1. チャンネル(lines)からデータ(line)を読み取る。クローズされた場合は終了
  2. バッファ(buf)にデータを格納
  3. データに検索対象文字列(pattern)が含まれない場合は、1へ戻る
  4. バッファに格納されている全ての行を出力する
  5. バッファを空にする
  6. 1へ戻る

おわりに

実際に必要となったのは、検索対象文字列の前後の行に色を付けて出力する処理だったので、もう少し複雑になりました。
そのコードは https://github.com/x-color/hlt/blob/master/cmd/hlt/highlight.go#L135 にあるので見てみたい方がいたらどうぞ。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0