grep maçtan önce ve sonra Nth ve Mth satırlarına dönecek


12

Ben grep ile ben alanları kullanabilirsiniz biliyoruz -Ave -Bbir maç önceki ve sonraki satırları çekin.

Ancak maçlar arasındaki tüm çizgileri çeker, ancak birçok çizgi belirtilir.

grep -r -i -B 5 -A 5 "match" 

Ben sadece 5 Almak istediğiniz inci bir maç öncesi hattı ve 5 inci eşleşti hattına ek olarak maçtan sonra çizgi arasındaki çizgiler olsun.

Bunu ile yapmanın bir yolu var mı grep?


1
Bunu sed'e pipetleyerek yapabilirsiniz. Bunu test ettim ve işe yaradı, ancak sadece dosyada 1 tam eşleşme olduğunda çalıştı: grep -r -i -B 5 -A 5 "match" | sed -e 1b -e '$!d'
Terrance

@Terrance öneri için teşekkür ederiz, bahsettiğiniz gibi, 1000 satırları topladığım için bu işe yaramayacak.
chollida


Sorun değil! Aldığınız cevapları görmekle ilgileniyorsunuz. =)
Terrance

bu bir dosyada mı yoksa birden çok dosyada mı?
Joshua Besneatte

Yanıtlar:


1

Kullanmak istediğiniz araca sift denir. Bu temelde steroidler üzerinde bir grep. Paralel olarak açın. Sift, tam olarak ne yapmak istediğinizi yapmak için çok sayıda seçeneğe sahiptir - özellikle, bir metnin ardından gelebilecek / gelmeyebilecek / gelmeyebilecek bir eşleşmeye göre belirli bir satırı döndürmek.

Sift, go dilinde yazıldığı gibi ana akım gnu olmadığını, ancak Linux'a kurulduğunu hayrete düşürüyor. BT, grep'in aynı şeyi yapmasının sadece haftalar sürdüğü tüm büyük miktarda metin kullanarak paralel olarak arama yapar.

Web sitesini eleyin - örneklere bakın


AskUbuntu'ya hoş geldiniz, cevap verdiğiniz için teşekkürler. Web sitesini elemek için bir bağlantı sağlamak yerine bu sorunu çözebilecek bir CLI örneği sağlamanız gerekir. Bu soru-cevap bölümüdür, teşekkürler.
Bernard Wei

12

Eğer:

cat file
a
b
c
d
e
f match
g
h
i match
j
k
l
m
n
o

Sonra:

awk '
    {line[NR] = $0} 
    /match/ {matched[NR]} 
    END {
        for (nr in matched)
            for (n=nr-5; n<=nr+5; n+=5) 
                print line[n]
    }
' file
a
f match
k
d
i match
n

+1, ancak anlambilimini açıklayabilir misiniz /match/ {matched[NR]}? Komut olarak bir dizi veya değişken görmedim. Eşleşen her satırın geçerli kayıt numarasını diziye mi koyuyor?
Joe

Bu garip bir tuhaflıktır: atama olmadan bir dizi öğesine başvurursanız, o anahtar diziye eklenir (değer olmadan). Sonra bu anahtar ifadede görünür key in array. Yaptığım şey, desenin göründüğü satır numaralarını hatırlamak
glenn jackman

6

Bu temelde Glenn'in çözümüdür, ancak Bash, Grep ve sed ile uygulanır.

grep -n match file |
    while IFS=: read nr _; do
        sed -ns "$((nr-5))p; $((nr))p; $((nr+5))p" file
    done

1'den küçük satır numaralarının sed hatası oluşturacağını ve dosyadaki satır sayısından büyük satır numaralarının hiçbir şey yazdırmayacağını unutmayın.

Bu sadece asgari. Yinelemeli çalışmasını sağlamak ve yukarıdaki satır numarası durumlarını işlemek biraz zaman alacaktır.


6

Sadece ile yapılamaz grep. Bir edseçenek varsa:

ed -s file << 'EOF' 
g/match/-5p\
+5p\
+5p
EOF  

Komut dosyası temel olarak şöyle der: / match / öğesinin her eşleşmesi için, bundan önce 5 satır, sonra bundan 5 satır, sonra 5 satır yazdırın.


5
@ubashu Eğer basit bir daire "grep ile yapılamaz" vererek OP için daha yararlı olacağını düşünüyor musunuz? OP'nin problemini çözmek için iyi bir alternatif olduğuna inandığım şeyi veriyorum. Yardım Merkezi'nden: "Özellikle, ne soruyor? Sorunuzun cevabının - veya uygun bir alternatif sunduğundan emin olun. Cevap 'bunu yapma' olabilir, ancak 'bunun yerine deneyin' de içermelidir. ."
JoL

edher zaman bir cevaptır, çünkü edstandart metin düzenleyicisidir.
tatlı

5
@ubashu Her ne kadar bir grepcevap olmasa da , "X ile yapamazsınız, ancak Y ile yapabilirsiniz, işte nasıl" sadece OP'nin sorusunu cevaplamakla kalmaz aynı zamanda bir alternatif de sağlarsınız bu işe yarar. Bu geçerli bir cevap türüdür.
Thomas Ward

5
awk '/match/{system("sed -n \"" NR-5 "p;" NR "p;" NR+5 "p\" " FILENAME)}' infile

Burada kullandığımız awk 'ın dış çağrılacak işlevi hatlarını yazdırmak için komut awk desenli eşleşti 5 ile inci öncesi ve maç sonrasında hatları.system(command)sedmatch

Sözdizimi kolaydır, harici komutun kendisini çift tırnak içine ve anahtarlarına koymanız ve komuta tam olarak geçmek istediğiniz şeylerden kaçmanız yeterlidir, awkkendisiyle ilgili diğer her şey tırnak işaretleri dışında olmalıdır. Yani aşağıdaki sed :

"sed -n \"" NR-5 "p;" NR "p;" NR+5 "p\" " FILENAME

çevirmek:

sed -n "NR-5p; NRp; NR+5p" FILENAME

NRkalıpla eşleşen satır numarasıdır matchve geçmekte FILENAMEolan geçerli dosya adının adıdır awk.


2

@ glenn'in örnek metin dosyasını kullanarak ve awk yerine perl kullanarak:

$ perl -n0E 'say /(.*\n)(?=(?:.*\n){4}(.*match.*\n)(?:.*\n){4}(.*\n))/g' ex

aynı sonuçları verir, ancak daha hızlı çalışır:

a
f match
k
d
i match
n

João, sen LQ inceleme kuyruğuna ve @waltinator gösterilmesini konum çok yakın zaman bir olmak, silmek için oy nebze ... daha ayrıntılı ;-) Ayrıca 1 LQ sıranın size çıkmak ... : P
Fabby

1
@JJoao Düşük kaliteli inceleme kuyruğu. Cevabınız muhtemelen% 90 kod olduğu için alındı.
wjandrea

1
@JJoao% 90 rakamı sadece benim açıklama şeklim. Aslında sezgisel taramaların ne olduğunu bilmiyorum.
wjandrea

1
Menos café, mais escrita! @JJoao : D ;-): D
Fabby

1
@Fabby: Sem café nada funciona: D - muhtemelen LCQ'da gösterilecekti (= düşük kahve kuyruğu)
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.