grep は find コマンドで実行しても正しい出力を生成しません

grep は find コマンドで実行しても正しい出力を生成しません

ls私のタスクは、コマンドを使用せずに現在のディレクトリ内のファイルの数を印刷することでしたwc

スクリプトに次の行を入力しました。

#!/bin/bash
find . -maxdepth 1 -type f \( ! -iname ".*" \) > list3
grep .* -c list3 > /dev/tty

出力は次のようになります。

..:0
.6.1c.sh.swp:1
list3:22

私の理解によれば、それは次のようになるはずです:22

なぜそれが機能しないのですか?

答え1

なぜgrep正しく動作しないのか

それが実際に探しているパターンであるgrepことを伝える必要があるため、これは機能しません。.*

grep '.*' -c list3

シングルクォートを使用しない場合、シェルは.*ディレクトリ内のすべてのファイル名を展開します。これはファイル名の拡張たとえばa.txt b.txt、次のgrepようになります。

grep a.txt b.txt -c list3

以来一重引用符拡大を防ぐには、これが最善の方法です。


コマンドが間違っている箇所grep:

ところで、ここでのパターンは間違った方向に進んでいます。.正規表現のピリオドはどれでも文字であり、ドットそのものではない。ページman詳細については、正規表現を参照してください。つまり、現在の正規表現は、「任意の文字を検索し、次に任意の文字のシーケンスを検索」するということです。かなり冗長です。

実際に一致させるつもりなら:

[ドット] [その他]

…ドットをエスケープする必要があります:

\.*

findコマンドを改善できる箇所:

何を取り除こうとしているのか分からない

\( ! -iname ".*" \)

コマンドfindは、現在の作業ディレクトリのドットをすべてのファイルの先頭に付加するため、ここでは何も削除されません。次のように実行することもできます。

find . -maxdepth 1 -type f

答え2

元の問題を解決するには、lsとのないファイルをカウントしますwc

純粋なシェル構文:

files=0
for i in *; do
    [ -f "${i}" ] && files=$((files+1))
done
echo ${files}

隠しファイルをカウントに追加するには、forループの前にグロブ設定を変更するだけです。

あるいは、findシェル拡張を楽しんでください:

echo $(($(find -maxdepth 1 -type f -printf '+1')))

関連情報