Grep 0 ile satır kaldır, ancak 0.2 değil mi?


12

İçeriği aşağıdakine benzer bir dosyam var.

0
0
0.2
0
0
0
0

Tek bir sıfır ile tüm satırları kaldırmam gerekiyor.
Kullanmayı düşünüyordum grep -v "0", ancak bu 0.2 içeren satırı da kaldırıyor. -wSeçeneği kullanabileceğimi gördüm , ama bu da işe yaramıyor.

Tek bir 0 içeren tüm satırları nasıl kaldırabilir ve tüm bu satırları 0 ile başlayarak nasıl tutabilirim?



1
@JulienLopez Bu sorunun bir kopyası değil. Bu soru, bir kelimeyi eşleştirmek ve -wburada başarısız olan ile cevaplanmakla ilgilidir .
Sparhawk

Neden grepbu görev için kullanmak zorundasın ? Ve tek bir sıfır ile tam olarak ne demek istiyorsun ? Bu bir XY problemine çok benziyor .
Roland Illig

1
@RolandIllig Yatmadan 1 saat önce oldu ve bitcoin özel anahtarları olup olmadığını kontrol etmek için 500.000 dizeden oluşan bir dizi işlemeye başlamak istedim ve eğer dengeyi elde edin. Bir dahaki sefere bakmak için zamanım vardı, binlerce dizeyi işledim ve sadece sıfır olmayan değerleri ayrıştırmak istedim.
Philip Kirkbride

Yanıtlar:


35
grep -vx 0

Gönderen man grep:

-x, --line-regexp
       Select only those matches that exactly match the whole line.
       For a regular expression pattern, this is like parenthesizing
       the pattern and then surrounding it with ^ and $.

-wbaşarısız olur çünkü ilk 0giriş 0.02bir "kelime" olarak kabul edilir ve bu nedenle bu satır eşleştirilir. Bunun ardından bir "sözcük olmayan" karakter gelir. Orijinal komutu -v, yani olmadan çalıştırırsanız bunu görebilirsiniz grep -w "0".


-FRegex desenleri kullanmadığımız için seçeneği de kullanabilirsiniz , sadece düz dize eşleme
glenn jackman

@glennjackman Belki bunu daha önce okudum, ama şimdi bulamıyorum. -F(Şaşırtıcı bir şekilde benim için) koşmak benzer bir zaman alıyor ya da biraz daha yavaş (~% 5-10) gibi görünüyor. Bu nedenle, avantajın ne olacağından emin değilim.
Sparhawk

2
RegEx motorunun çok sık ve çok yaygın olarak kullanılması, çok verimli bir versiyonunu kullanmış olmaları mümkündür, ancak "basit bir arama" muhtemelen 30 yıldır güncellenmemiştir.
Nelson

@Sparhawk: büyük grepolasılıkla metakarak içermeyen normal ifadeler için özel bir durum var, çünkü bu yaygın bir kullanım örneğidir. Daha fgrepyavaş olması şaşırtıcıdır , ancak kısa bir desen derlerken bu özel durumu fark etmenin ek yükünün, büyük bir dosyayı tarama zamanına karşı ihmal edilebilir olması şaşırtıcı değildir. (Bu kadar hızlı gitmek için özel bir durum gerekiyorsa, bir karakter sınıfına sahip bir desen veya x.*y.)
Peter Cordes

Ancak, bu aslında aşırı bir basitleştirme çünkü giriş aslında çok sayıda kısa satır (tek bir dev dizge değil). Satır ayırıcı olarak satırsonu grepdışında herhangi bir karakteri tanıyıp tanımadığımı unutuyorum \n. Değilse, örtük ^ve $ yine gibi sabit dize aramaya dönüşebilir strstr(big_buf, "\n0\n"). (Ya da 0\nbir tamponun başlangıcında). Ama sadece potansiyel olarak büyük bir tamponda ilk maçı aramakla kalmıyoruz, verimli bir şekilde filtrelemek istiyoruz. Ama her neyse, teoride evet, her satırın başında sadece 2 baytlık bir memcmp ve hem fgrep hem de grep'in bunu göreceğini umuyorsunuz.
Peter Cordes

28

Grep ile:

grep -v "^0$" file

^satır başı, satır $sonu anlamına gelir.


2
Kullanıcının istediği şey: sadece 1 "0" içeren satırlardan kaçının.
Olivier Dulac

1
Bunun gibi çift tırnak içine gerçek bir dolar işareti koymak olmaz.
user541686

@mehrdad regex ile büyük bir sorun değil, genellikle ya son char ya da bir sonraki olmayacak[a-Z0-9]
Sampo Sarrala - codidact.org

14

İken grep olabilir (diğer cevaplar açıkça göstermek gibi) Bunun için kullanılacak, haydi bir adım geri alır ve gerçekte ne istediğini düşünelim:

  • Sen içeren bir dosya var sayılar
  • Sayısal değere dayalı olarak filtreleme yapmak istiyorsunuz .

Normal ifade karakter dizisi verilerini yorumlar. Sayıları bilmiyorlar, sadece bireysel rakamlar (ve bunların düzenli kombinasyonları) hakkında. Özel durumunuzda bu sınırlamanın etrafında basit bir saldırı olmasına rağmen, sonuçta bir gereksinim uyuşmazlığıdır.

grepBurada kullanmak için çok iyi bir neden olmadığı sürece (örneğin ölçtüğünüz için ve çok daha verimli olduğu ve verimliliğiniz sizin için çok önemli olduğu için), farklı bir araç kullanmanızı öneririz.

awk, örneğin, sayısal karşılaştırmalara göre filtre uygulayabilir, örneğin:

awk '$1 == 0' your_file

Ancak, sıfırdan büyük sayılar içeren tüm satırları almak için:

awk '$1 > 0' your_file

Normal ifadeyi seviyorum, harika bir araç. Ama tek araç bu değil . Söylediği gibi, sahip olduğunuz tek grepşey her şey normal bir dile benziyor.


3
Ben yürekten burada daha zarif olabileceğini kabul ediyorum ... ancak, aynı zamanda belki kullanıcının beklediğinden biraz daha fazla maç (0 olarak değerlendirilen her sayısal değer). Yani, printf '0\n1\n-1\na\nb\n0\n0 also\n0.0\n-0.0\n0*0\n' | awk '($1 == 0)'eşleşir: 0, 0.0ve -0.0... ve ayrıca 0 also! Sadece "0" değil. (bu bazen gerekli olan, bazen gerekmeyen). Kullanıcı yalnızca "0" istiyorsa: awk '/^0$/' (veya grep '^0$'). Ayrıca düzenlemelisiniz: Kullanıcının !testi olumsuzlamak için eklemesi gerekir, böylece gizlenir 0(ve diğer sıfırlar) ve gerisini görüntüler. ie:awk '!( $0 == 0)'
Olivier Dulac

1
@Olivier veya dize değerini kontrol edin:$1 == "0"
glenn jackman

1
@OlivierDulac Bunun sadece eşitlik değil, keyfi bir sayısal karşılaştırma olduğunu vurgulamak için (veya eşdeğer olarak ) >yerine açıkça kullandım . Diğer yorumunuza gelince, bu tamamen doğrudur, ancak daha sonra dize karşılaştırma bölgesinde ve eserleri kullanarak mevcut çözümde geri döndük (tabii ki de çalışıyor). !=! (… == …)grepawk
Konrad Rudolph

@KonradRudolph fair points :)
Olivier Dulac

1
@glennjackman: güzel numara. Ama sonra OP testi yapmayı tercih eder$0=="0"
Olivier Dulac

5

grep's -w, orijinal dizgiyi sözcük ve sözcük olmayan bileşenlere (harfler, rakamlar veya alt çizgi hariç) ayıracak şekilde biraz kıvrıktır. Zaten karşılaştığı için, 0içinde geçerli bir kelime oluşturucu 0.02, çizgiyi kaldırmak için olumsuzlama mantığını iddia etmişti.

Kullanımı sedsadece bu maç tam kelimeleri kaldırmak için bu bağlamda kolay biraz edilir

sed '/^0$/d' file

3

Silmek istediğiniz satırlar yalnızca bir 0 sonraki satır içerdiğinde , aşağıdaki komutu vererek bu satırları seçebilirsiniz:

grep -v "^0$"

Bu yalnızca tekrarlarını basacaktır 0olan bir satırın sonunda ve bir satırın başında aynı anda. -vSeçenek daha sonra seçimimizi ters çevirir.


1
Bu cevap Arkadiusz Drabczyk ile neredeyse aynı, ancak unutmuşsunuz -v, bu yüzden işe yaramıyor.
Sparhawk

Haklısın. Cevabını gönderirken yazıyordum, bu yüzden zaten verildiğini görmedim. Bu bölümü -vseçenekle yanlış anladım , teşekkürler!
majesticLSD

0
  • \ b - kelime kenarlığı

grep -v "\b0\b"

  • satır başı, deseniniz ve satır sonu ile eşleşir

grep -v "^0$"

  • veya @Sparhawk önerdiği gibi -vx lineregexp

-w çalışır, ancak sizin durumunuzda 0.2 iki kelimedir, çünkü nokta karakteri bir sözcük ayırıcıdır.


grep -v "\b0\b"burada gerçekten çalışmıyor. Hangi grep sürümünü kullanıyorsunuz?
Arkadiusz Drabczyk

grep (BSD grep) 2.5.1-FreeBSDmacOS ve grep (GNU grep) 2.16ubuntu üzerinde çalışıyor
Jakub Jindra

1
GNU normal ifade kullanımı \<ve \>kelime sınırları olarak, ancak bu-w
glenn jackman

0

PCRE özellikli olduğunu varsayarak çeşitlilik adına başka bir cevap grep

grep -Pv "^0(?!\.)"

Bu gerçekleştirdiği bir negatif ileri yönlü ile başlayan satırları maç için 0ve olmayan bir nokta ile izledi. Ardından, -veşleşmeyen satırları atar. Burada eylem görebilirsiniz


1
Bu aynı zamanda 0123OP'nin istediği gibi olmayan hatları da kaldıracak
iruvar

0

Yalnızca tek bir 0 olmayan herhangi bir satırın bir periyodu olduğunu varsayarsak

grep '\.' file

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.