Belirli bir desen kümesinden desenle başlamayan çizgileri kaldırma


11

Ben böyle veriler içeren bir dosya var:

report aaaaaaaa  
-  ..  
-th bbbbbbbbb  
-to ccccccccc

.. --.

Soru: Aşağıdaki dizelerle başlamayan herhangi bir satırı kaldırmak istiyorum:

report  
-th  
-to

bu, arzu çıktısının tüm bu orta istenmeyen noktaları ve karmaları kaldıracağı ve şöyle görüneceği anlamına gelir:

report aaaaaaaa  
-th bbbbbbbbb  
-to ccccccccc

sed/ awk/ grep/ vb çalışacak herhangi bir çözüm.

Yanıtlar:


15

sedDosyayı yerinde değiştirmek için kullanma :

sed -i '/^\(report\|-t\(h\|o\)\)/!d' your_file

Bu sed, kalıpla eşleşmeyen tüm satırları silmeyi söyler. Desenin kendisi ^(satır başlangıcı), ardından ya ya reportda -tardından ya hda olur o.

Bunun gerçek yerinde değişiklik olmadığını unutmayın: sedgeçici bir yedek kopya oluşturur ve orijinal dosyanın üzerine yazar.

sedOrijinal dosyanın yedek bir kopyasını saklamak istiyorsanız (dosya kritik veriler içeriyorsa iyi bir fikir olabilir), -iyedek dosya oluşturmak için anahtara bir uzantı verin :

sed -i'.bak' -e '/^\(report\|-t\(h\|o\)\)/!d' your_file

your_fileorijinali değiştirir ve yedek oluşturur your_file.bak.

Bir yan not

Lütfen niyetlerimi yanlış yorumlamayın veya bu konuda rahatsız etmeyin, ancak benzer regex / metin işleme ile ilgili birçok sorunuz olduğunu fark ettim. Sana öğrenmeyi başlatmak için tavsiye sed, awkve grepkendi başınıza verimlilik kadar yardım hızına. Yine, beni yanlış anlamayın, yardım etmek için çok mutluyum (buradaki çoğu insan gibi); sadece bu araçları günlük kullanımınız için almaktan büyük fayda sağladığınızı düşünüyorum.

İnsanların burada ne kadar yararlı olduğunu kanıtlamak için, aşağıdaki yorumlarda @ slm'nin önerisini düşünün ve sorularınız için istediğiniz zaman bu sohbet odasına uğrayabilirsiniz .


1
Normal ifadeniz gereksiz yere şifreli görünüyor. Aslında üç seçeneği açıkça listelemiş olmanızdan daha fazla karakter kullandığınızı düşünüyorum.
nispio

1
@nispio biliyorum, ancak söz konusu dosya büyükse daha verimli olacaktır.
Joseph R.6

İlginç. Normal ifadeleri her zaman uzunluk veya okunabilirlik açısından ölçtüm. İnfaz hızı hakkında hiç düşünmedim. Neyin hızlı olduğunu yargılamak için nasıl değerlendirildiklerini yeterince bildiğimi sanmıyorum, ancak bunun uygulamaya özel olduğunu da varsayıyorum, değil mi?
nispio

3
Joseph'in yardım etmeye istekli olduğu hakkında söylediklerini tekrarlayarak, Soru-Cevap tarzına uymayan genel sorularınız varsa, her zaman bu sitenin sohbet odasında bizimle sohbet etmeyi deneyebilirsiniz. chat.stackexchange.com/rooms/26/unix-and-linux . Birkaçımız orada yaşıyor 8-)
slm

@slm Bunun için teşekkür ederim. Cevabıma ekleyeceğim.
Joseph R.6

10

Bunun için basit grep kullanabilirsiniz:

$ grep -e '^report\|^-th\|^-to' filename

1
Çok fazla tasarruf değil, ama -th/ ile -tobirleştirebilirsiniz -t[ho].
Kevin

grep -eveyaegrep
Olivier Dulac

2

Kullanma sed:

sed -n -e '/^report\|^-th\|^-to/p' filename

Çok fazla tasarruf değil, ama -th/ ile -tobirleştirebilirsiniz -t[ho].
Kevin

1
@Kevin Bu doğru. Cevabının yorumunda Joseph R. ile konuşmamı gör.
nispio

2

Kullanma awk:

awk '/^report|^-t[ho]/' file

Çok fazla tasarruf değil, ama -th/ ile -tobirleştirebilirsiniz -t[ho].
Kevin

1

Soru soran iki noktaya değindi:

  • "rapor" veya "-th" veya "-to" ile başlamayan herhangi bir satırı kaldırmak istemek.
  • istenen çıktı "tüm bu istenmeyen istenmeyen noktaları ve karmaları (sic)" kaldırmalıdır

Çözümler şu anda birinci noktayı ve dolayısıyla ikinciyi de ele almaktadır. Ancak dosyanın daha büyük olduğunu ve şöyle göründüğünü varsayın:

report aaaaaaaa  
-  ..  
-th bbbbbbbbb  
-to ccccccccc
anything else
.. --.
-tp ddd
-tq eee
     -  -----

OP'nin ikinci noktasına hitap etmek gerekmiyor mu?

sed -r -i.bak '/^[ |.|-]*$/d' input-file 

sadece boşluklar, noktalar ve çizgiler içeren muhtemelen istenmeyen çizgileri kaldırma ve gerisini, ne olursa olsun, tutma işi yapar.
Her iki yaklaşımın da riskin dosyanın doğasının uygun şekilde tanımlanmamış olması olduğunu düşünürüm.


0

Perl Kullanımı:

perl -ne 'print if /^report|^-t[ho]/' filename > newfile

veya yerinde düzenlemek için (örneğin sed, perlgeçici bir yedekleme de yapar, böylece bu, yerinde düzenlemede doğru değildir ):

perl -i.bak -ne 'print if /^report|^-t[ho]/' filename

Bu, adlandırılan orijinal dosyanın bir kopyasını oluşturur ve orijinal dosyanızın filename.baküzerine düzenlenmiş sürümün üzerine yazar.

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.