単語を含むすべての行をOK
ディレクトリから再帰的に出力したい。しかし、結果から除外する必要があるいくつかの拡張機能があります。
*~
*.map
*.js except *.debug.js
私は試した:
grep -r --exclude={*~,*.map} "OK" /some/dir
結果からそれらのすべての非デバッグ.js
ファイルを削除する方法がわからない場合を除きます。
単語を含むすべての行をOK
ディレクトリから再帰的に出力したい。しかし、結果から除外する必要があるいくつかの拡張機能があります。
*~
*.map
*.js except *.debug.js
私は試した:
grep -r --exclude={*~,*.map} "OK" /some/dir
結果からそれらのすべての非デバッグ.js
ファイルを削除する方法がわからない場合を除きます。
回答:
私はgrep
それらを削除するために1秒だけ通過させます:
grep -r --exclude={\*~,\*.map} "OK" bar/ | grep -vP '(?<!debug)\.js'
-v
パターンにマッチしない行印刷、試合を逆転させ-P
、私たちが使ってみましょうPerl互換の正規表現できます負lookbehindsを。この特定の正規表現は、一致します.js
されていないことでprececeded debug
のみという(私たちは試合を反転しているので)その手段.js
のファイルが印刷されます。
しかし@QuestionOverflowコメントをint指摘したように、それは、フィルタリングの意図しない副作用かもしれないライン含めるOK
とjs
するのでgrep -v
出力全体に適用されるだけでなく、ファイル名。これを回避するには、コロンを追加するだけです(これgrep
は、ファイル名とファイルの内容を区切るために使用されます)。
grep -r --exclude={*~,*.map} "OK" bar/ | grep -vP '(?<!debug).js:'
入力行にが含まれているfoo.js:
場合、またはファイル名にが含まれて:
いる場合は、引き続き失敗します。したがって、確かに、別のアプローチを使用します。
grep -Tr --exclude={*~,*.map} "OK" bar/ | grep -vP '(?<!debug).js\t'
-T
原因となるgrep
ファイル名とファイルの内容との間にタブを印刷します。したがって、単に\t
正規表現の末尾にa を追加すると、ファイル名に対してのみ一致し、行の内容とは一致しません。
それでも、使用find
することは関係なくより意味があるかもしれません。
find
は、この種の場合にはおそらくより適しています。grep
あなたが指摘したように、正しいことをするのは難しいかもしれません:)。
failglob
シェルにオプションが設定され ている場合、ソリューションは失敗bash: no match: --exclude=*~
します。たとえば、GLOBパターン引数を引用--exclude
して、シェル展開から非表示にする必要があります。たとえば--exclude={\*~,\*.map}
私find
はファイルを見つけて結果をパイプするために使用しますxargs
:
$ find . -type f \! -name "*~" \
\! -name "*.map" \
\! \( -name "*.js" -and \! -name "*.debug.js" \) \
-print0 | xargs -0 grep "OK"
これは、すべてのファイルを検索していない「一致*~
」、「*.map
」または「*.js
ではなく*.debug.js
」。
を使用find
すると、かなり複雑なルールを簡単に検索できます。このアプローチにより、doubleで発生する可能性があるように、誤って誤検知を削除することがなくなりますgrep
。
-exec grep OK {} +
代わりに使用してxargs
、余分なプログラムを回避することもでき ます。
-exec +
ないことに注意してください。これは-exec \;
、とほとんど同じように、できるだけ少ないコマンドを実行しますxargs
。
zsh
あなたが行うことができます。
setopt extendedglob
grep OK some/dir/**/^(*~|*.map|(^*debug).js)
もちろん、引数リストが長すぎない場合は、いつでも実行できます。
printf '%s\0' some/dir/**/^(*~|*.map|(^*debug).js) | xargs -0 grep OK
zsh
:autoload zargs
andzargs some/dir/**/^(*~|*.map|(^*debug).js) -- grep OK
出力が順不同で表示されるのを気にしない場合(そうする場合は、並べ替えることができます):
grep -r --exclude={*~,*.map,*.js} "OK" /some/dir **/*.debug.js
これには、シェル**
が再帰的グロビングをサポートしている必要がありますshopt -s globstar
。zshはデフォルトで実行され、bashは実行後に実行され、ksh93は実行後に実行されますset -o globstar
。
**
シェルでのサポートがなければ、2つのgrepコマンドを使用できます。
grep -r --exclude={*~,*.map,*.js} "OK" /some/dir
grep -r --include=*.debug.js "OK" /some/dir
**
が、余分な引数に問題があるため**/*.debug.js
、grepがOK
ディレクトリとして解釈されます。実行してみましたか?
使用できますripgrep
。デフォルトでは、隠しファイルを無視し、ファイルを尊重します.gitignore
。
次のパラメーターを使用して、包含ルールまたは除外ルールを指定できます。
-g
/--glob GLOB
指定したグロブに一致する検索用のファイルとディレクトリを含めるか除外します。
-t
/--type TYPE
TYPEに一致するファイルのみを検索します。複数のタイプフラグを指定できます。
-T
/--type-not TYPE
TYPEに一致するファイルを検索しません。
--type-list
フラグを使用して、使用可能なすべてのタイプをリストします。
以下にいくつかの簡単な例を示します。
rg -Tjs "OK" # Excludes *.js, *.jsx, *.vue files.
rg -tpy "OK" # Includes Python files.
rg --type-add 'map:*.map' -tmap PATTERN # Excludes *.map files.
rg -g '!*.js' -g '*.debug.js' PATTERN # Excludes *.js apart of *.debug.js.
ここでは除外するための完全なソリューションです*.~
、*.map
、*.js
、ではありません*.debug.js
。
rg -g '*.*' -g '!*.~' -g '!*.map' -g '!*.js' -g '*.debug.js' "OK"
テスト:
$ touch file.~ file.map file.js file.debug.js file.txt file.md
$ rg --files
file.debug.js
file.js
file.map
file.md
file.txt
$ rg -g '*.*' -g '!*.~' -g '!*.map' -g '!*.js' -g '*.debug.js' --files
file.debug.js
file.md
file.txt
OK
を含み.js
、同じ行にありますか?