"grep -Rl" は、適切な空間をサポートする vi 引数で生成されます。

"grep -Rl" は、適切な空間をサポートする vi 引数で生成されます。

私は次のようなことをしようとしています。

vi `grep -Rl 'keyword'`

しかし、ファイル名のスペースをサポートしたいと思います。

vi "`grep -Rl 'keyword'`"

するいいえ必要な操作を実行すると、grep出力を\ nを含む単一の引数に変換します。

頑張った

vi "`grep -Rl 'keyword'`| xargs"

ビューは良くなりましたが、結果はまだ単一の引数です(今では\ nの代わりにスペースが含まれています)。

これを行うための良い方法はありますか? Bashは優れており、POSIX規格に準拠していることも利点です。

PS。

-R オプションはすべての grep 実装で動作するわけではなく、bash は``

答え1

使用find:

find . -type f -exec grep -q 'pattern' {} \; -exec vi {} +

これは、現在のディレクトリ内または下のすべての一般ファイルで一致する行を探しますpattern。見つかったファイルに対してvi開始されます。

これらのファイルが何百もの場合、viバッチファイルが呼び出されます。-exec vi {} +ファイルごとに1回呼び出されるように変更されました-exec vi {} \;vi

grep -q実際には、出力にはまったく関心がなく、grep終了状態にのみ関心があるため、これを使用します。

これは有効なUnixファイル名を受け入れ、POSIXと完全に互換性があります(再帰でgrepはありません)。

答え2

どうですか?

grep -Rl 'pattern' | xargs -d '\n' vi

-dこのオプションがどのくらいPOSIXyかわかりません。

GNUツールがある場合は、すべてのファイル名を受け入れることをお勧めします。

grep -Rlz 'pattern' | xargs -0 vi

答え3

Bashで一致するファイル名があまりにも多くないと仮定すると、$(getconf ARG_MAX)別のオプションはglobstarの下の拡張を繰り返し**、一致するファイル名の配列を作成することです。

shopt -s globstar
matching_files=()
for entry in **
do
  [ -f "$entry" ] || continue
  grep -q 'pattern' -- "$entry" && matching_files+=("$entry")
done
vi -- "${matching_files[@]}"

ループは現在のディレクトリとその下に隠されていないファイルとディレクトリを探します。私たちが実行する最初のテストは、通常のファイルがあることを確認することです。その場合は、grepQuiet / Silentを実行して目的のモードを取得します。ファイルにパターンが含まれている場合は、そのファイル名を match_files 配列に追加します。最後に、vi配列の安全に拡張されたアイテムのリストを使用して作業します。

隠しファイルやディレクトリも検索するには、を設定しますshopt -s dotglob

関連情報