リバース grep が一致するすべての行が見つからない

リバース grep が一致するすべての行が見つからない

編集する:とても複雑にしました。これはリバース grep とは関係ありません。ただ使用しても同じ結果が得られますgrep -x -f stop.txt < in.txt。不用語ファイルのwho前にある場合、whose結果はですwho。不用語ファイルの順序が変わるin.txtと、2行が見つかります。 grepを全く理解していないようです。


ファイルから不用語を含む行を削除するのと同じように、逆方向grepを機能させることはできません。不用語が提供される順序は結果に影響を与えます。

2つのファイルがあるとしましょう。入力ファイルin.txt:

who
whose

そして、不用語のリストを含むファイルは次のとおりですstop.txt

who
whose

in.txt逆grep検索を使用しての停止単語を「フィルタリング」すると、次のような結果がstop.txt得られます。

$ grep -vx -f stop.txt < in.txt
whose
$

stop.txt私が次に変更した場合のみ

whose
who

私は得る:

$ grep -vx -f stop.txt < in.txt
$

不用語を含むファイルの単語の順序がなぜ重要なのかわかりません。

答え1

スキーマファイルを含める

$ od -bc shortlong
0000000   167 150 157 012 167 150 157 163 145 012
           w   h   o  \n   w   h   o   s   e  \n
0000012
$ od -bc longshort
0000000   167 150 157 163 145 012 167 150 157 012
           w   h   o   s   e  \n   w   h   o  \n
0000012

grep macOS(2.5.1-FreeBSD)を使用していくつかの変更をテストできます。

$ grep -x -f shortlong shortlong
who
$ grep -x -f shortlong longshort
who
$ grep -x -f longshort shortlong
who
whose
$ grep -x -f longshort longshort
whose
who

who最初の項目が長いwhose一致を隠すとき。これはバグのようです。

問題は、式がファイルから出てくるときにのみ発生-fし、同等の(希望する)式が引数として提供されるときには発生しません。

$ grep -x -E 'who|whose' shortlong
who
whose
$ grep -x -E 'who|whose' longshort
whose
who
$ grep -x -E 'whose|who' shortlong
who
whose
$ grep -x -E 'whose|who' longshort
whose
who

GNU grep(3.7)にはこの問題はありません(grep現在のバージョンのOpenBSDも同様です):

$ ggrep -x -f shortlong shortlong
who
whose
$ ggrep -x -f shortlong longshort
whose
who
$ ggrep -x -f longshort shortlong
who
whose
$ ggrep -x -f longshort longshort
whose
who

したがって、このエラーを回避するには、バージョン2.5.1-FreeBSDを使用しないか、grep非端末値をforパラメータに置き換えてファイルに正規表現を設定します。\n|grep -E

$ paste -s -d \| shortlong
who|whose
$ grep -x -E -- "$(paste -s -d \| shortlong)" shortlong
who
whose

シフトについて

理想的には、正規表現の置換では、長い文字列を短い文字列の前にリストする必要があります。他の極端なケースの中でこれは、人々がlongshortファイルやwhose|whoテーブルを好む必要があることを意味します。

grep(エラーがない場合)正しい結果を得るために表示されますが、他の正規表現エンジンは最初の一致で停止するため、一致させるには最長の一致を最初にリストする必要があります。

$ printf 'who whoses the whosefolk' |
grep -o -E 'who|whose|whosefolk'
who
whose
whosefolk
$ printf 'who whoses the whosefolk' |
perl -nle 'print for /who|whose|whosefolk/g'
who
who
who
$ printf 'who whoses the whosefolk' |
perl -nle 'print for /whosefolk|whose|who/g'
who
whose
whosefolk

関連情報