暗黙的なマルチパターンマッチングが欲しいそしてモード間は、複数のgrepを順次実行するのと同じです。
grep pattern1 | grep pattern2 | ...
それでは、これを似たようなものに変換する方法は?
grep pattern1 & pattern2 & pattern3
パラメータを動的に構築してすべてが文字列に収まる必要があるため、単一のgrepを使用したいと思います。フィルタの使用は grep ではなくシステム機能であるため、これについての議論ではありません。
この質問を以下と混同しないでください。
grep "pattern1\|pattern2\|..."
これは一つですまたはマルチパターンマッチング。私は〜を探していますそしてパターンマッチング。
答え1
パターンリストの各パターンに一致する行を見つけるにはagrep
(元のパターン、今フラッシュ、関連性がないよりもTRE正規表現ライブラリ)は、次の構文を使用して実行できます。
agrep 'pattern1;pattern2'
GNUを使用すると、grep
PCREサポートでビルドするときに次のことができます。
grep -P '^(?=.*pattern1)(?=.*pattern2)'
そしてASTgrep
:
grep -X '.*pattern1.*&.*pattern2.*'
(sを一致文字列.*
として追加して、<x>&<y>
<x>
<y>
正確に、a&b
そのような文字列は一致しないため、絶対一致しません。はい同時にa
)b
。
パターンが重ならない場合は、次のこともできます。
grep -e 'pattern1.*pattern2' -e 'pattern2.*pattern1'
最良のポータブル方法はおそらくawk
上記のようになります。
awk '/pattern1/ && /pattern2/'
または以下を使用してsed
:
sed -e '/pattern1/!d' -e '/pattern2/!d'
またはperl
:
perl -ne 'print if /pattern1/ && /pattern2/'
これらのすべてには異なる正規表現構文があります。
awk
//終了状態のパターンに一致する行があるかどうかを反映しません。以下を行うには:sed
perl
awk '/pattern1/ && /pattern2/ {print; found = 1}
END {exit !found}'
perl -ne 'if (/pattern1/ && /pattern2/) {print; $found = 1}
END {exit !$found}'
またはコマンドをgrep '^'
。
zgrep
潜在的にgzipで圧縮されたファイルの場合、通常はシェルスクリプトラッパーインを使用し、上記grep
のソリューションのいずれかを使用するか(その実装を使用できないため、grep
ast-openソリューションではありません)、モジュールを使用できます。入力時にファイルを透明に解凍します。grep
zgrep
PerlIO::gzip
perl
perl -MPerlIO::gzip -Mopen='IN,gzip(autopop)' -ne '
print "$ARGV:$_" if /pattern1/ && /pattern2/' -- *.gz
zgrep
(ファイルが十分に小さい場合は、各ファイルに対して実行せずに内部で解凍を実行するよりも少なくとも効率的ですgunzip
。)
答え2
重要なgrepバージョンを指定していません。一部の正規表現エンジンは、「&」を使用してANDを介して複数の一致を許可しますが、これは非標準で移植できない機能です。ただし、少なくともGNU grepはこれをサポートしていません。
OTOH、grepをsed、awk、perlなどで簡単に置き換えることができます(重みが増える順にリストされています)。 awkを使用すると、コマンドは次のようになります。
awk '/regexp1/ && /regexp2/ && /regexp3/ {印刷}'
そして、簡単な方法でコマンドラインで指定するように設定できます。
答え3
答え4
patterns
各行にパターンが含まれている場合は、次のことができます。
awk 'NR==FNR{a[$0];next}{for(i in a)if($0!~i)next}1' patterns -
または、正規表現の代わりに部分文字列と一致します。
awk 'NR==FNR{a[$0];next}{for(i in a)if(!index($0,i))next}1' patterns -
noneを印刷するのではなく空の場合は、すべての入力行を印刷するには、またはinにpatterns
置き換えます。NR==FNR
FILENAME==ARGV[1]
ARGIND==1
gawk
これらの関数は、パラメータで指定された各文字列を部分文字列として含む行をSTDINに出力します。ga
grep allを表し、大文字とgai
小文字を無視します。
ga(){ awk 'FILENAME==ARGV[1]{a[$0];next}{for(i in a)if(!index($0,i))next}1' <(printf %s\\n "$@") -; }
gai(){ awk 'FILENAME==ARGV[1]{a[tolower($0)];next}{for(i in a)if(!index(tolower($0),i))next}1' <(printf %s\\n "$@") -; }