私はしばしば次のコマンドを実行します。
find … -exec grep … --color=always -l {} \+
時にはVimで一致するファイルを開く必要があります。
しかし、最も確実な方法は何ですか?
一方通行そんな気がする
vim $(find … -exec grep … {} \+)
もう一つのアプローチはxargs
。
これら2つの方法と異なる方法について知る必要がある長所/短所/問題がありますか?
答え1
vim $(find path/ -exec grep -l 'pattern' {} +)
引用符なしのコマンド置換であるため、結果のスペースとパス名の拡張に対してトークン化が行われます。つまり、ファイルがa b
一致した場合、Vimは誤って開きますa
。b
ファイルが*
一致すると、残念ながらそのディレクトリ内のすべてのファイルに展開されます。適切な解決策は
find path/ -type f -exec grep -q 'pattern' {} \; -exec vim {} +
Grepはq
uietモードで実行されます。各ファイルには戻り値のみが使用されます。その0
場合は、ファイル内の一致するものを見つけて、そのファイルをVimに渡します。
{} \;
Grep が一度に 1 つのファイルを分析することを示します。{} +
すべてのファイルはGrepに引数として渡され、次を使用すると一致するものが見つかります。どのこれらのファイル数に応じて0
シャットダウン状態が発生するため、すべてのファイルが Vim で開きます。一方{} +
、Vimの場合、見つかった各ファイルは単一のVimプロセスのバッファに保存されます。変化を感じるために変化を試すことができます。
作業速度を上げる必要がある場合:
'pattern'
正規表現ではなく固定パターンの場合は、Grap-F
にフラグを追加してください。grep -lZ
、Xargs、および特別なシェル構成もプロセスを高速化する必要があります。Stefan Chazerasの答え。
そしてここXargs、Find、Vimのもう1つの類似したユースケースです。
答え2
GNUツール(--color=always
すでにGNU拡張)とKshスタイルのプロセス交換をサポートするシェルの使用:
xargs -r0a <(grep -rlZ pattern .) vim
または:
xargs -r0a <(find . ... -exec grep -lZ pattern {} +) vim
そしてzsh
:
vim ${(0)"$(find . ... -exec grep -lZ pattern {} +)"}
4.4+ バージョンbash
:
readarray -td '' files < <(find . ... -exec grep -lZ pattern {} +)
vim "${files[@]}"
これにより、grep
実行される呼び出しの数が最小限に抑えられます。要点は、出力をNULで区切られたファイル名で指定して、GNUの引数拡張フラグを介して別の引数に確実に分割できるgrep
ようにすることです。vim
xargs -0
zsh
0
bash
readarray -td ''
では、zsh
次のこともできます。
vim ./**/*(...e['grep -q pattern $REPLY'])
(ここでは、メソッド...
のように追加できる追加修飾子を示しますfind
。)
ただし、これは使用された方法と同様に、ファイルごとに1回の呼び出しが実行されるため、速度が大幅に遅くなることを意味しfind -exec grep -q pattern {} ';'
ますgrep
。
zsh
--color=always
デフォルトから値を変更して変更すると、-Z
最初のアプローチが機能します。他のシェルは変数へのNUL保存をサポートしていないため、機能せず、使用または無効にする必要がある分割をもたらす単語のファイル名の生成も実行します。IFS
IFS=$'\0'
IFS=$' \r\n\0'
$IFS
set -o noglob
set -f
検索結果を繰り返すのはなぜ悪い習慣ですか?find
安定して見つかったファイルのリストを処理する方法に関する追加情報を提供します。
答え3
2つの異なる方法:
- 結果をクイックフィックスリストに配置します。
find ... -exec grep -Hn {} + >results
vim -q results
または清掃部(shではない)
vim -q <(find ... -exec grep -Hn {} +)
- 使用
:grep -R
と:Cfilter
:
vim
:grep -R ...
:packadd cfilter
:Cfilter[!]
関連:help
コマンドを参照してください。
:cnext
どちらか他のコマンドを使用して一致をナビゲートできます:help quickfix
。