Metin dosyasındaki bir sözcüğün oluşum sayısını komut satırına göre nasıl sayabilirim?


43

Bir satırda büyük bir JSON dosyasına sahibim ve komut satırını, bir sözcüğün oluşum sayısını saymak için kullanmak istiyorum. Bunu nasıl yapabilirim?


Sözcüğün JSON verilerinin hem tuşlarında hem de değerlerinde eşleşip eşleşmemesi gerektiği, yani { "key": "the key" }dizeyi keybir veya iki kere sayıp saymayacağı net değildir .
Kusalananda

Yanıtlar:


45
$ tr ' ' '\n' < FILE | grep WORD | wc -l

Nerede tr, yenisatırlar ile boşluk değiştirir grepbütün sonuçlanan WORD eşleşen hatları ve filtreler wcsayımları kalan olanlar.

Bir grep seçeneğini wckullanarak bile parçayı kaydedebilir -c:

$ tr ' ' '\n' < FILE | grep -c WORD

-cSeçenek POSIX tarafından tanımlanır.

Sözcükler arasında boşluk olduğu garanti edilmezse, değiştirmek için başka bir karakter (sınırlayıcı olarak) kullanmanız gerekir. Örneğin alternatif trparçalar

tr '"' '\n'

veya

tr "'" '\n'

çift ​​veya tek tırnak yerine geçmek istiyorsanız. Tabii ki, aynı tranda birden fazla karakteri değiştirmek için de kullanabilirsiniz (farklı boşluklar ve noktalama işaretleri düşünün).

WORD'i saymanız ancak prefixWORD, WORDsuffix veya prefixWORDsuffix'i saymamanız gerekiyorsa, WORD kalıbını start / satır sonu işaretleyicileri içine alabilirsiniz:

grep -c '^WORD$'

Bizim kelime bağlamında kelime başlangıç ​​/ bitiş işaretleyicisine eşdeğerdir:

grep -c '\<WORD\>'

Boşluk yoksa, yani alan adı tırnak işaretleri ile çevrilmişse? örneğin "alanı"
mythz

@ mythz: Sonrasında tırnakları tr ile yeni satırlarla değiştirirsiniz. Cevabı güncelleyeceğim.
maxschlepzig

1
Bu cevap birçok yönden yanlıştır. Belirsizdir: trHer durumda asla işe yaramayacak örnekler önermek yerine, işi yapan bir emir nasıl geleceğini açıklamalısınız . Ayrıca, aradığınız sözcüğü içeren sözcüklerle de eşleşir. grep -o '\<WORD\>' | wc -lÇözüm çok daha üstündür.
sam hocevar

1
@Sam, sorulan soru biraz açık kalıyor, eğer aranan bir kelimenin 'WORD' veya '\ <WORD \>' gibi aranması gerekiyorsa - iki yolu da okuyabilirsiniz. 2. yoldan ve sadece 2. yoldan okursanız bile, cevabım sadece tek yoldan sadece yanlış olur. ;) Ve 'grep -o' çözümü yalnızca, POSIX tarafından belirtilmeyen -o seçeneğini destekliyorsa üstündür. Eh, tr'nin kullanımının onu çağırmak için egzotik olduğunu düşünmüyorum. belirsiz ...
maxschlepzig

1
@Kusalananda, peki, hala bir oluşum. Ancak bu tür alt dize eşleşmelerini saymak istemiyorsanız, lütfen cevabımın son paragrafını ve önceki yorumumu burada okuyun.
maxschlepzig

24

GNU grep ile bu çalışır: grep -o '\<WORD\>' | wc -l

-o Her çizginin eşleşen parçalarını ayrı bir satıra yazdırır.

\<Bir kelimenin başlangıcını ve bir kelimenin \>sonunu (Perl'inkine benzer şekilde \b) belirtir; bu, kelimenin ortasında bir dizgeyle eşleşmemenizi sağlar.

Örneğin,

$ python -c 'bunu al' | grep '\ <bir \>'
Olmalı biri sadece tercihen ve - tek bunu yapmak için --obvious yol.
İsim boşlukları harika fikirlerden biri - hadi daha fazlasını yapalım!
$ python -c 'bunu al' | grep -o '\ <biri \>'
 tek 
tek 
tek 
$ piton -c 'bu ithal' | grep -o '\ <one \>' | wc -l
3

1
Ya da sadecegrep -wo WORD | wc -l
Stéphane Chazelas 10:18

10

Bu ne yazık ki GNU ile çalışmıyorcoreutils .

grep -o -c WORD file

Platformunuzda çalışıyorsa, zarif ve oldukça sezgisel bir çözümdür; ama GNU millet hala düşünüyor.


2
Benim hatam, böcek hala açık: savannah.gnu.org/bugs/?33080
üçlü

1
Çok kötü, bu en şık olurdu
MasterScrat

Bu benim için çalıştı!
ThisaruG

Bu yanlış. Bu WORD desenli satır sayısını sayar. OP toplam oluşum sayısını istiyor.
Pierre B,

@PierreB Bu yüzden GNU'nun grepburada bir böceği olduğunu söylüyorum . POSIX’den ne anlama geliyor ne anlama geliyor -cve -obu şu anda taşınabilir değil. Yorumunuz için teşekkürler; Bu cevabı güncelledim.
üçlü

7
sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl 

Bu komut aşağıdakileri yapar:

  1. Tüm alfanümerik olmayan karakterleri boş bir alanla değiştirin.
  2. Tüm satır sonları da boşluklara dönüştürülür.
  3. Tüm çoklu boşlukları tek bir boş alana azaltır
  4. Tüm boşluklar şimdi satır sonlarına dönüştürülür. Satırdaki her kelime.
  5. 'Merhaba' ve 'merhaba' ifadelerinin farklı kelimeler olmasını önlemek için tüm kelimeleri küçük harfe dönüştürür.
  6. De metni sıralar
  7. Eşit çizgileri sayar ve kaldırır
  8. En sık kullanılan kelimeleri saymak için tersi sıralar
  9. Tüm içindeki posotion kelimesini bilmek için her kelimeye bir satır numarası ekleyin.

Örneğin, ilk Linus Torvald mesajını analiz etmek istersem:

Kimden: torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds) Haber Grupları: comp.os.minix Konu: Minix'te en çok ne görmek istersiniz? Özet: yeni işletim sistemim için küçük anket Message-ID: <1991Aug25.205708.9541@klaava.Helsinki.FI> Tarih: 25 Ağu 91 20:57:08 GMT Organizasyonu: Helsinki Üniversitesi

Herkese merhaba minix kullanarak -

386 (486) AT klonu için (ücretsiz) bir işletim sistemi yapıyorum (sadece bir hobi, gnu gibi büyük ve profesyonel olmayacak). Bu nisandan beri demlendi ve hazırlanmaya başladı. Minix'te insanların sevdiği / sevmediği şeyler hakkında herhangi bir geri bildirim istiyorum, çünkü işletim sistemim buna benzer (dosya sisteminin aynı fiziksel düzeni (pratik nedenlerden dolayı)).

Şu anda bash (1.08) ve gcc (1.40) öğelerini taşıdım ve işler iyi görünüyor. Bu, birkaç ay içinde pratik bir şeyler elde edeceğim ve çoğu insanın hangi özellikleri istediğini bilmek istiyorum. Herhangi bir öneriniz açıktır, ancak bunları uygulayacağım için söz vermiyorum.

Linus (torvalds@kruuna.helsinki.fi)

PS. Evet - herhangi bir minix kodu içermez ve çok dişli bir fs'ye sahiptir. Protable DEĞİLDİR (386 görev değiştirme vb. Kullanır) ve sahip olduğum tek şey olduğu gibi muhtemelen AT-harddisks'ten başka hiçbir şeyi desteklemeyecektir :-(.

Linus.txt adlı bir dosya oluşturuyorum , içeriği yapıyorum ve ardından konsola yazıyorum:

sed -e 's/[^[:alpha:]]/ /g' linus.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl 

Çıkış şöyle olurdu:

 1        7 i
 2        5 to
 3        5 like
 4        5 it
 5        5 and
 6        4 minix
 7        4 a
 8        3 torvalds
 9        3 of
10        3 helsinki
11        3 fi
12        3 any
13        2 would
14        2 won
15        2 what
16        ...

Yalnızca ilk 20 kelimeyi görselleştirmek istiyorsanız:

sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl | head -n 20

Tr 'AZ' 'a-z' komutunun henüz UTF-8'i desteklemediğini , böylece yabancı dillerde APRÈS'nin aprÈs olarak çevrileceğini not etmek önemlidir.

Yalnızca bir kelimenin oluşumunu aramak istiyorsanız, sonuna bir grep ekleyebilirsiniz:

sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl | grep "\sword_to_search_for$"

Search_freq adlı bir komut dosyasında :

#!/bin/bash
sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl | grep "\s$1$"

Komut çağırılmalıdır:

 search_freq word_to_search_for

sed: -e expression #2, char 7: unterminated s 'komutu`, bu da tüm kelimeleri sayar, değil mi? Fakat OP sadece belirli bir soruyu sordu. Ayrıca biraz açıklama güzel olurdu.
phk

Üzgünüm bir hata yaptım. Bu emri tekrar okudum artı cevabı yorumladım. Benim düşünceme göre, sorudan, sadece bir kelimenin veya bir sıklıkta bulunma sıklığının varlığını almak isteyip istemediğini bilmek imkansız. Ancak sadece bir kelime almak isterseniz, sonunda bir grep ekleyebilirsiniz.
Roger Borrell,

3

Kelimenin anahtarlarında mı yoksa JSON verilerinin değerlerinde mi eşleşmek istediğinize bağlı olarak, yalnızca anahtarlardan mı yoksa yalnızca verilerden değerler çıkarmak istediğinizde. Aksi halde, hem anahtarlar hem de değerler olarak ortaya çıkarlarsa bazı kelimeleri çok fazla sayabilirsiniz.

Tüm anahtarları çıkarmak için:

jq -r '..|objects|keys[]' <file.json

Bu, mevcut şeyin bir nesne olup olmadığını tekrar tekrar test eder ve eğer öyleyse, anahtarları çıkarır. Çıktı, satır başına bir tuş listesi olacaktır.

Tüm değerleri çıkarmak için:

jq -r '..|scalars' <file.json

Bu benzer şekilde çalışır, ancak daha az adım vardır.

Daha sonra yukarıdakilerin çıkışını ( grep -c 'PATTERN'tuşlara veya değerlere göre bir deseni eşleştirmek için) veya grep -c -w -F 'WORD'( tuşlar veya değerlerde bir kelimeyle eşleştirmek için ) veya grep -c -x -F 'WORD'(tam bir anahtar veya değerle eşleştirmek için) veya benzeri Saymayı yap.


0

Buna benzer bir şeyim var: "number":"OK","number":OK"bir satırda birden çok kez tekrar ediyorum .

Benim basit "Tamam" sayacım:

sed "s|,|\n|g" response | grep -c OK


-1

Ben oluşum sayısını bulmak için awk komutunu kullandık

örnek dosya

kedi dosyası1

praveen ajay 
praveen
ajay monkey praveen
praveen boy praveen

komut:

awk '{print gsub("praveen",$0)}' file1 | awk 'BEGIN{sum=0}{sum=sum+$1}END{print sum}'

çıktı

awk '{print gsub("praveen",$0)}' file1 | awk 'BEGIN{sum=0}{sum=sum+$1}END{print sum}'

5

Ya da sadece awk '{sum+=gsub("praveen","")} END {print sum+0}'.
G-Man

Cevabım için neden aşağı oy verdiğini bana bildirin
Praveen Kumar BS
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.