現在のディレクトリ内のすべてのファイルで用語の出現をどのようにカウントしますか?


10

現在のディレクトリ内のすべてのファイルで用語の出現をどのようにカウントしますか?-およびサブディレクトリ(?)

これを行うには、以下を使用することを読みましたgrep。正確なコマンドは何ですか?

また、上記の他のコマンドで可能ですか?

回答:


12

grep+ を使用wc(これは、同じ行に複数の用語が出現する場合に対応します):

grep -rFo foo | wc -l
  • -rin grep:現在のディレクトリ階層を再帰的に検索します。
  • -Fin grep:パターンではなく固定文字列と一致します。
  • -oin grep:一致するものだけを出力します。
  • -lin wc:行数を出力します。
% tree                 
.
├── dir
│   └── file2
└── file1

1 directory, 2 files
% cat file1 
line1 foo foo
line2 foo
line3 foo
% cat dir/file2 
line1 foo foo
line2 foo
line3 foo
% grep -rFo foo | wc -l
8

一番いいと思います。
Jacob Vlijm 2015年

1
@JacobVlijmありがとう!あなたのようなIすぎて(とすでにそれをupvoted)
KOS

PCREs実験的なものであるため、使用すべきではないと思います
Edward Torvalds

2
PCREは「実験的」ではありませんが、常にgrepにコンパイルされるわけではありません(これが、必要なときにpcregrepを使用する理由です)。ただし、この場合、質問は、「パターン」ではなく固定文字列である可能性が高い「用語」について尋ねるため、不要です。したがって、-Fおそらくより高速になります。
dannysauer 2015年

2
@dannysauer PCREを使用した理由は、いくつかの(間違った)理由で、同じ行の複数のオカレンスに一致させる必要がある思ったからです。の-F代わりに使ってみませんでした-P。素晴らしい提案をありがとうござい-Fます。を使用して更新します。
kos 2015年

8

grep -Rc [term] *それを行います。-Rあなたは再帰的に現在のディレクトリとそのサブディレクトリのすべてを検索したいフラグ手段。これ*はファイルセレクタの意味です。すべてのファイルです。この-cフラグはgrep、発生回数のみを出力します。ただし、単語が1行に複数回出現する場合は、1回だけカウントされます。

からman grep

  -r, --recursive
          Read all files under each directory, recursively, following symbolic links only if they are on the command line.
          This is equivalent to the -d recurse option.

   -R, --dereference-recursive
          Read all files under each directory, recursively.  Follow all symbolic links, unlike -r.

ディレクトリにシンボリックリンクがない場合、違いはありません。


-cフラグを追加できますgrep。その後、grepはそれ自体をカウントし、あなたは必要ありませんwc
Wayne_Yux

あなたは--前に置きたいかもしれません*
エドワード・トーヴァルズ

2
*あなたはすべてのそれらを逃すようにのみ、非ドットファイルに展開されます。"。"だけを使用する方が理にかなっています。とにかく引数を再帰的に処理するので、ドットファイルが取得されます。ここでのより大きな問題は、これが単語の出現回数ではなく、行数になる可能性があることです。用語が1行に複数回出現する場合、 "grep -c"によって1回だけカウントされます
dannysauer '06 / 11/15

2

小さなpythonスクリプトで:

#!/usr/bin/env python3
import os
import sys

s = sys.argv[1]
n = 0
for root, dirs, files in os.walk(os.getcwd()):
    for f in files:
        f = root+"/"+f      
        try:
            n = n + open(f).read().count(s)
        except:
            pass
print(n)
  • 名前を付けて保存しますcount_string.py
  • 次のコマンドを使用して、ディレクトリから実行します。

    python3 /path/to/count_string.py <term>
    

ノート

  • 用語にスペースが含まれる場合は、引用符を使用してください。
  • 1行に複数回出現する場合も、用語のすべての出現を再帰的にカウントします。

説明:

# get the current working directory
currdir = os.getcwd()
# get the term as argument
s = sys.argv[1]
# count occurrences, set start to 0 
n = 0
# use os.walk() to read recursively
for root, dirs, files in os.walk(currdir):
    for f in files:
        # join the path(s) above the file and the file itself
        f = root+"/"+f
        # try to read the file (will fail if the file is unreadable for some reason)
        try:
            # add the number of found occurrences of <term> in the file
            n = n + open(f).read().count(s)
        except:
            pass
print(n)

2
Pythonの男;) +1
TellMeWhy 2015年

1
ところで何rootfのため?
TellMeWhy 2015年

1
rootは、現在のディレクトリの「上」を含むファイルへのパスfです。または、 os.path.join()使用することもできますが、より冗長です。
Jacob Vlijm 2015年

1
そしてn = n + open(f).read().count(s)
TellMeWhy 2015年

2
これは、OPが要求した用語のすべての出現をカウントする唯一の回答のようです。申し訳ありませんが、grepを使用するすべてのソリューションは、用語が出現するすべての行をカウントします。そのため、用語を3回含む行は1回だけカウントされます。
Joe

2

@kosの良い答えの変形として、カウントの項目化に興味がある場合は、grepの-cスイッチを使用して発生をカウントできます。

$ grep -rFoc foo
file1:3
dir/file2:3
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.