行の開始^アンカーは機能しますが、行の終わり$アンカーはgrepコマンドで機能しないのはなぜですか?

行の開始^アンカーは機能しますが、行の終わり$アンカーはgrepコマンドで機能しないのはなぜですか?

UNIXでは非常に新しいものですが、プログラミングには新しいものではありません。 MacBookで端末を使用してください。クロスワードプーリで構成された単語のリストを管理して検索するために、Grepコマンドとそのバリエーションを試しました。十分簡単に​​見えますが、簡単な事例でなければならないと思っていたことが初期に詰まっていました。

私が入るとき

grep "^COW" masternospaces.txt

欲しいものを手に入れました。 COWで始まるすべての単語のリストでした。

しかし、私が入るとき

grep "COW$" masternospaces.txt

COWで終わる単語のリスト(多くの単語があります)を取得すると予想しましたが、何も返されませんでした。

ファイルはプレーンテキストファイルで、各行はすべて大文字の1つの単語(または空白のない単語の構文)です。

ここで何が起こるのかご存知ですか?

答え1

grep@steeldriverが述べたように、予想とは異なる行末スタイルが原因で問題が発生する可能性があります。

行末の確認

これを使用して、hexdump行末の形式がどのように指定されたかを正確に確認できます。私が好きな形式を使用することをお勧めします。

hexdump -e '"%08_ad (0x%08_ax)    "8/1 "%02x ""   "8/1 "%02x "' -e '"    "8/1 "%_p""|"8/1 "%_p""\n"' masternospaces.txt

出力で行末(0a-> LF0d->)を確認してくださいCR。非常に簡単な例は次のとおりです。

$ hexdump -e '"%08_ad (0x%08_ax)    "8/1 "%02x ""   "8/1 "%02x "' -e '"    "8/1 "%_p""|"8/1 "%_p""\n"' masternospaces.txt
00000000 (0x00000000)    4e 6f 20 43 4f 57 20 65   6e 64 69 6e 67 0d 0a 45    No COW e|nding..E
00000016 (0x00000010)    6e 64 69 6e 67 20 69 6e   20 43 4f 57 0d 0a          nding in| COW..

dos形式の行末を参照してください0d 0a

行末の変更

あなたは見ることができますここまたはここさまざまなツールを使用して行末を変更するさまざまな方法がありますが、ワンタイム操作には常にvi / vimを使用できます。

vim masternospaces.txt
:set fileformat=unix
:wq

grepに変更はありません

grep行末に関係なく一致させる場合は、常に次のように行末を指定できます。

grep 'COW[[:cntrl:]]*$' masternospaces.txt

空白行が表示されたら、-v次のオプションを使用して、実際に一致するものがあるかどうかを確認できますcat

grep 'COW[[:cntrl:]]*$' masternospaces.txt | cat -v

私が個人的に好き

grepを使用して出力を正規化することもできますsed

sed -n '/COW^M*$/{;s/^M//g;p;};' masternospaces.txt

^Mキーボード入力で取得できる場所。Ctrl-V Ctrl-M

役に立ったことを願っています!

答え2

\r以前にgrepを削除する別の方法:

... | dos2unix | egrep 'COW$' | ...

[[:cntrl:]]私は物事を長く覚えていないので、それは非常に明確であることが好きです。

答え3

grepで「標準」の正規表現構文を使用できます(例:@user43791の返信)、grep には入力境界を表す他の識別子があります。

行全体の始まりと終わりを表す一致は、\`(代わりにバックティック)^\'(代わりにアポストロフィ$)です。

したがって、元のコマンドでは次のように使用します。 grep "COW\'" masternospaces.txt

注:andでエスケープしない限り、および?+文字通り処理され、正規表現スタイルセレクタ対応項目になります。\?\+

源泉:grep正規表現構文

答え4

「COW $」bashがgrepのパラメータを設定すると、「COW」と解釈されます。ここで、$ はエスケープ記号なので、「$」は「」として扱われます。 $に何もない場合、bashシェルはそれを空の文字列として解釈するので、代わりに 'COW$' masternospaces.txtをgrepする必要があります。

関連情報