Kamuycikap - SentenceDataBase

日々の勉強の記録を気分で書き綴るブログ

CUIで動く高速なgrep代替をchromebookで「silversercher-ag」

高速検索を実現するコマンドラインツール「ag」

LinuxMacOS等のUnix系ターミナルを使っている人なら、必ずお世話になるツール「Grep
これの高速版として未だ人気を獲得しているagをChromebookLinuxターミナルにインストールして使ってみる

インストール

Linuxターミナルを起動して下記のコマンドを実施。
あっという間にインストール完了

hoge@penguin:~$ sudo apt install silversearcher-ag
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
以下のパッケージが新たにインストールされます:
  silversearcher-ag
アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 0 個。
38.6 kB のアーカイブを取得する必要があります。
この操作後に追加で 127 kB のディスク容量が消費されます。
取得:1 https://deb.debian.org/debian buster/main arm64 silversearcher-ag arm64 2.2.0-1 [38.6 kB]
38.6 kB を 1秒 で取得しました (43.8 kB/s)                  
debconf: delaying package configuration, since apt-utils is not installed
以前に未選択のパッケージ silversearcher-ag を選択しています。
(データベースを読み込んでいます ... 現在 67056 個のファイルとディレクトリがインストールされています。)
.../silversearcher-ag_2.2.0-1_arm64.deb を展開する準備をしています ...
silversearcher-ag (2.2.0-1) を展開しています...
silversearcher-ag (2.2.0-1) を設定しています ...
man-db (2.8.5-2) のトリガを処理しています ...

動作確認

そのままagとだけ入力してみる。
うまくインストールできていれば、agのヘルプが表示される。*1

hoge@penguin:~$ ag

Usage: ag [FILE-TYPE] [OPTIONS] PATTERN [PATH]

  Recursively search for PATTERN in PATH.
  Like grep or ack, but faster.

Example:
  ag -i foo /bar/

Output Options:
     --ackmate            Print results in AckMate-parseable format
  -A --after [LINES]      Print lines after match (Default: 2)
  -B --before [LINES]     Print lines before match (Default: 2)
     --[no]break          Print newlines between matches in different files
                          (Enabled by default)
  -c --count              Only print the number of matches in each file.
                          (This often differs from the number of matching lines)
     --[no]color          Print color codes in results (Enabled by default)
     --color-line-number  Color codes for line numbers (Default: 1;33)
     --color-match        Color codes for result match numbers (Default: 30;43)
     --color-path         Color codes for path names (Default: 1;32)
     --column             Print column numbers in results
     --[no]filename       Print file names (Enabled unless searching a single file)
  -H --[no]heading        Print file names before each file's matches
                          (Enabled by default)
  -C --context [LINES]    Print lines before and after matches (Default: 2)
     --[no]group          Same as --[no]break --[no]heading
  -g --filename-pattern PATTERN
                          Print filenames matching PATTERN
  -l --files-with-matches Only print filenames that contain matches
                          (don't print the matching lines)
  -L --files-without-matches
                          Only print filenames that don't contain matches
     --print-all-files    Print headings for all files searched, even those that
                          don't contain matches
     --[no]numbers        Print line numbers. Default is to omit line numbers
                          when searching streams
  -o --only-matching      Prints only the matching part of the lines
     --print-long-lines   Print matches on very long lines (Default: >2k characters)
     --passthrough        When searching a stream, print all lines even if they
                          don't match
     --silent             Suppress all log messages, including errors
     --stats              Print stats (files scanned, time taken, etc.)
     --stats-only         Print stats and nothing else.
                          (Same as --count when searching a single file)
     --vimgrep            Print results like vim's :vimgrep /pattern/g would
                          (it reports every match on the line)
  -0 --null --print0      Separate filenames with null (for 'xargs -0')

Search Options:
  -a --all-types          Search all files (doesn't include hidden files
                          or patterns from ignore files)
  -D --debug              Ridiculous debugging (probably not useful)
     --depth NUM          Search up to NUM directories deep (Default: 25)
  -f --follow             Follow symlinks
  -F --fixed-strings      Alias for --literal for compatibility with grep
  -G --file-search-regex  PATTERN Limit search to filenames matching PATTERN
     --hidden             Search hidden files (obeys .*ignore files)
  -i --ignore-case        Match case insensitively
     --ignore PATTERN     Ignore files/directories matching PATTERN
                          (literal file/directory names also allowed)
     --ignore-dir NAME    Alias for --ignore for compatibility with ack.
  -m --max-count NUM      Skip the rest of a file after NUM matches (Default: 10,000)
     --one-device         Don't follow links to other devices.
  -p --path-to-ignore STRING
                          Use .ignore file at STRING
  -Q --literal            Don't parse PATTERN as a regular expression
  -s --case-sensitive     Match case sensitively
  -S --smart-case         Match case insensitively unless PATTERN contains
                          uppercase characters (Enabled by default)
     --search-binary      Search binary files for matches
  -t --all-text           Search all text files (doesn't include hidden files)
  -u --unrestricted       Search all files (ignore .ignore, .gitignore, etc.;
                          searches binary and hidden files as well)
  -U --skip-vcs-ignores   Ignore VCS ignore files
                          (.gitignore, .hgignore; still obey .ignore)
  -v --invert-match
  -w --word-regexp        Only match whole words
  -W --width NUM          Truncate match lines after NUM characters
  -z --search-zip         Search contents of compressed (e.g., gzip) files

File Types:
The search can be restricted to certain types of files. Example:
  ag --html needle
  - Searches for 'needle' in files with suffix .htm, .html, .shtml or .xhtml.

For a list of supported file types run:
  ag --list-file-types

ag was originally created by Geoff Greer. More information (and the latest release)
can be found at http://geoff.greer.fm/ag

使い方

カレントディレクトリ以下から文字列「hoge」を検索する

$ ag hoge

*2

/var/log以下から文字列「hoge」を検索する

$ ag hoge /var/log

マッチした文字「kthread」が含まれるファイル名だけを表示する

$ ag -l kthread
init/main.c
init/Kconfig
mm/kmemleak.c
mm/vmscan.c
(……略……)

あきらかにマッチするはずの文字列が含まれているのにヒットしない時

テキストファイルに、あきらかに存在する文字列がヒットしない場合。
その多くは、該当のテキストファイルをバイナリファイルとして認識してしまっている可能性が高い。
検索結果にこのように表示されているかも。

$ ag -ua hoge
Binary file {something file} matches. 

どうも原因は、文字コードUTF-8以外になっているからの様子。
Windowsから引っ張ってきたファイル群に対してagする場合は注意が必要。
*3

# DOS → UTF8 一括変換
find . -type f | xargs nkf -w --overwrite

# CRLF → LF 一括変換
find . -type f | xargs file | grep CRLF | awk -F: '{print $1}' | xargs nkf -Lu --overwrite

*1:マニュアルもインストールされるので、man ag でmanページを閲覧できる

*2:とくにオプションを付けなくても、$ grep -r hoge と同等の動きになる。

*3:この症状はgrepでも同様に発生する。。。