grep構文の先頭または末尾にワイルドカードが配置されている場合、なぜ動作が異なるのですか? [コピー]

grep構文の先頭または末尾にワイルドカードが配置されている場合、なぜ動作が異なるのですか? [コピー]

たとえば、現在のディレクトリに特定の拡張子を持つファイルがいくつあるかを計算したいとします。

私は以下を使用しました:

ls | grep ".txt" | wc -l

これは次のように機能します。

ls | grep ".txt*" | wc -l

しかし、なぜこれも機能しませんか?

ls | grep "*.txt" | wc -l

拡張の前にワイルドカードを使用するときにgrep式で機能しないような理由は何ですか?なぜ最後には動作しないのですか?

ベストアンサー1

$ ls *.txt

このコマンドは、シェルグローブを使用して始まるすべての名前を一覧表示します.txt

$ ls | grep "*.txt"

このコマンドは、現在の作業ディレクトリにあるすべての(隠されていない)ファイルを一覧表示し、その出力をに送信しますgrep。これは正規表現に基づくファイル名と一致します/*.txt/

/*.txt/

この正規表現は、使用される正規表現のスタイルに応じて、次のパターンと一致することがあります。

*    -- zero or more characters of any type (or possibly only a literal '*'), followed by
.    -- exactly one character of any type, followed by 
txt  -- the literal string 'txt', followed by anything

正規表現で*「0個以上の先行サブ式」を表すワイルドカードですが、シェルグロブワイルドカードとは異なります。関連して、.これはピリオドではなく、1文字のワイルドカードです(?シェルグローブのワイルドカードに似ています)。したがって、この式は(やはり正規表現のスタイルに応じて)、のいずれかと一致しますが、file.txt実際sometxtfilephoto_of_a_txt_file.pngは一致しませんtxtfile(前の文字がと一致しないためですtxt)。したがって、txtこの正規表現を使用すると、ファイル名の先頭を除いてリテラル文字列がどこにでも表示されることを知ることが重要です。

.txt次に終わるファイル名をキャプチャするより良い正規表現/\.txt$/

\.  -- A literal .
txt -- The literal string 'txt'
$   -- End of input

lsしたがって、パイピングに固執する場合grep(解析された出力がなぜ悪い考えなのかを説明する本を今すぐ読まないでくださいls)、おそらく次のようにします。

$ ls | grep "\.txt$"

を使用している場合は、wcそうする必要はありません。 grep数えることができます:

$ ls | grep -c "\.txt$"

おすすめ記事