Geçerli dizindeki tüm dosyalarda bir terimin her oluşumunu nasıl sayacaksınız?


10

Geçerli dizindeki tüm dosyalarda bir terimin her oluşumunu nasıl sayacaksınız? - ve alt dizinler (?)

Bunu yapmak için bunu okudum grep; tam komut nedir?

Ayrıca, başka bir komutla yukarıdakiler mümkün müdür?

Yanıtlar:


12

Kullanımı grep+ wc(aynı satırda terimin birden bulunuşu için bu irade hitap):

grep -rFo foo | wc -l
  • -rin grep: geçerli dizin hiyerarşisinde özyinelemeli olarak arama yapar;
  • -Fin grep: desen yerine sabit bir dizeyle eşleşir;
  • -oin grep: yalnızca eşleşmeleri yazdırır;
  • -lin wc: satır sayısını yazdırır;
% 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

Bence en güzel olanı.
Jacob Vlijm

1
@JacobVlijm Teşekkürler! Ben de seninkini seviyorum (ve zaten oyladı)
kos

PCREsDeneysel oldukları için kullanılmaması gerektiğini düşünüyorum
Edward Torvalds

2
PCRE'ler "deneysel" değildir, ancak her zaman grep'te derlenmezler (bu yüzden onlara ihtiyaç duyduğumda pcregrep kullanıyorum). Bu durumda, gereksizdirler, çünkü soru muhtemelen herhangi bir tür desen değil, sabit bir dize olan bir "terim" soruyor. Yani, -Fmuhtemelen daha hızlı olurdu.
dannysauer

2
@dannysauer PCRE'leri kullandım çünkü bazı (yanlış) sebeplerden dolayı aynı hatta birden fazla oluşumla eşleşmeleri gerektiğini düşündüm , ama aslında değiller. Bunun -Fyerine kullanmayı denemedim -P. -FGerçekten burada daha iyi uyuyor kullanarak güncelleme büyük öneri için teşekkürler .
kos

8

grep -Rc [term] *bunu yapacak. -RBayrak özyinelemeli geçerli dizin ve onun alt dizinleri tüm arama yapmak istediğiniz anlamına gelir. *Tüm dosyaları: Bir dosya seçici anlamıdır. -cBayrak yapan grepçıktılı olaylar sadece dizi. Ancak, sözcük tek bir satırda birden çok kez oluşursa, yalnızca bir kez sayılır.

Gönderen 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.

Dizininizde hiçbir sembolik bağ yoksa, hiçbir fark yoktur.


-cbayrağını ekleyebilirsiniz grep. Sonra grep kendini sayar ve ihtiyacınız yokwc
Wayne_Yux

daha --önce koymak isteyebilirsiniz*
Edward Torvalds

2
*Tüm bu kaçırma böylece sadece, sigara dotfiles genişleyecektir. Sadece "." Kullanmak daha mantıklı. çünkü argümanları yinelemeli olarak tekrar işleyeceksiniz - ve bu nokta dosyaları alacak. Buradaki en büyük sorun, bunun bir kelimenin meydana gelme sayısını değil satır sayısını alabileceğidir. Terim bir satırda birden çok kez görünüyorsa, "grep -c" ile yalnızca bir kez sayılır
dannysauer

2

Küçük bir python betiğinde:

#!/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)
  • Farklı kaydedin count_string.py.
  • Koştur dizinden komutuyla:

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

notlar

  • Terim boşluk içeriyorsa, tırnak işareti kullanın.
  • Bir satırda birden çok oluşum olsa da, terimin her tekrarını yinelemeli olarak sayar.

Açıklama:

# 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 adamı ;) +1
TellMeWhy

1
btw nedir rootve ne fiçin?
TellMeWhy

1
rootgeçerli dizinin "yukarısını" içeren dosyanın yolu f, dosyadır. Alternatif olarak, os.path.join()kullanılabilir, ancak daha ayrıntılıdır.
Jacob Vlijm

1
Ya n = n + open(f).read().count(s)?
TellMeWhy

2
Bu , OP'nin talep ettiği gibi terimin tüm oluşumlarını sayan tek yanıt gibi görünmektedir . AFAIK, grep kullanan tüm çözümler terimin gerçekleştiği tüm satırları sayar, bu yüzden üç kez terimi içeren bir satır sadece bir olay olarak sayılır.
Joe

2

@ Kos'un güzel cevabının bir çeşidi olarak, sayıları sıralamakla ilgileniyorsanız, olayları saymak için grep'in -canahtarını kullanabilirsiniz:

$ grep -rFoc foo
file1:3
dir/file2:3
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.