Sen grep kullanabilirsiniz olacağını düşünüyorum, fakat iki kere kullanmak gerekir. (Tek bir grep kullanamazsınız, çünkü ERE'nin bir dizeyi iptal etme yolu yoktur, yalnızca tek karakterlerle eşleşecek bir parantez ifadesini iptal edebilirsiniz.)
Aşağıdakiler GNU grep v2.5.1 ile test edilmiştir. Eğer (muhtemelen olmayan taşınabilir) kelimesi sınırlayıcı olarak \<
ve \>
kullanabilirsiniz:
$ word="ab"
$ < input.txt egrep "(\<$word\>.*){3}" | egrep -v "(\<$word\>.*){4}"
abc ab cds ab abcd edfs ab
abcdefghijklmnop ab cdab ab ab
$ < input.txt egrep "(\<$word\>.*){2}" | egrep -v "(\<$word\>.*){3}"
kkmd ab jnabc bad ab
buradaki fikir o zaman, kelimenin N oluşumları ile giriş dosyası hatlarından ayıklamak ve bunun sonucunda gelen şerit olacak olmasıdır
herhangi N + 1 oluşumu olan çizgiler. Tabii ki N'den daha az olan hatlar, ilk grep tarafından eşleştirilmeyecek.
Veya, biraz mazoşist hissediyorsanız ayrıca, saf bash bu yapabilir:
#!/usr/bin/env bash
# Salt to taste
word="ab"; num=3
# Pull content into an array. This isn't strictly necessary, but I like
# getting my file IO over with quickly if possible.
readarray lines < input.txt
# Walk through the array (or you could just walk through the input file)
for this in "${lines[@]}"; do
# Initialize this line's counter array
declare -A words=()
# Break up the words into array elements
x=($this)
# Step though the array, counting each unique word
for y in "${x[@]}"; do
((words[$y]++))
done
# Check the count for "our" word
[ "0${words[$word]}" -eq $num ] && echo "$this"
done
:
$ word="ab"; num=3
$ readarray lines < input.txt
$ for this in "${lines[@]}"; do declare -A words=(); x=($this); for y in "${x[@]}"; do ((words[$y]++)); done; [ "0${words[$word]}" -eq "$num" ] && echo "$this"; done
abc ab cds ab abcd edfs ab
abcdefghijklmnop ab cdab ab ab
kolay okunması (ya komut dizisi) dışarı Broken Bu eğlenceli değil miydi? :)
Ama bu
awk
seçenek benim için en mantıklı. GNU awk'e bağlı olmayan taşınabilir bir tek liner (yani OS X, BSD, vb.)
Bu "ilginç" kelimesi için sayım
num
olarak belirtilen ne ise o çizgiyi baskı, her satırda kelimeleri saymak için bir ilişkisel dizi inşa ederek çalışır
. Yukarıdaki bash betiği ile aynı temel kavram, ama awk bunu daha iyi yapmamızı sağlıyor.
"sed" veya "awk" işlevlerini kullandığınızda, dosyanın üzerine dönmenize gerek yoktur. Bu dillerin zaten içsel olarak yaptıkları şey bu. – pfnuesel
@pfnuesel biliyorum ama hat üzerinden hat kontrol etmenin başka bir yolunu bilmiyordum – Papanash
Hattın satırını kontrol ederek, 'sed' yapan şey bu. – pfnuesel