Bir kalıpla eşleşen satırlar nasıl bulunur ve silinir?


14

Çok satır içeren bir dosyada ile başlayan satırları silmek istiyorum HERE IT IS.

Bunu yalnızca komut satırı araçlarını kullanarak nasıl yapabilirim?


2
Biraz sıradışı olsa da, şunu kullanabilirsiniz vimşöyle: vim '+g/^HERE IT IS/d' +wq test.txt;)
Doorknob

@Doorknob, bunu işaret ettiğiniz için teşekkür ederim. Aslında vim
micgeronimo

Yanıtlar:


29

Deneyin sed:

sed -i '/^HERE IT IS/d' <file>

UYARI: Şunların -ianahtarını kullanırken yedek almak daha iyidir sed:

sed -i.bak '/^HERE IT IS/d' <file>

Orijinal dosya olduğu gibi kalır <file>.bakve değiştirilen dosya kalır <file>.


Eşleşen dizeden sonra newline karakterini nasıl koyabilir ve newline'a yazabilirim?
micgeronimo

2
sed -i 's/^HERE IT IS/HERE IT IS\n/' <file>
heemayl

1
@micgeronimo: yardım etmekten mutluluk duyar. Düzenlemelerimi kontrol edin lütfen.
heemayl

6
@micgeronimo, temizlenebilecek / silinebilecek yorumlar yerine, orijinal sorunuzda gerçekten cevaplanmasını istediğiniz soruyu sormaya çalışın (düzenleyebileceğinizi unutmayın). Kullanabilirsiniz sed '/^HERE IT IS/G' file.
steeldriver

1
Sed kullanımı çok pro.
LakshyaAg

18

Aldığınız çok iyi grepve sedcevaplara ek olarak , aynı şeyi yapabilen diğer bazı araçlar:

  • Birkaç Perl yolu:

    perl -ne '/^HERE IT IS/ || print' file > newfile
    perl -ne 'print if !/^HERE IT IS/' file > newfile
    perl -ne 'print unless /^HERE IT IS/' file > newfile
    

    -iDosyayı yerinde düzenlemek için anahtarı örneklerden herhangi birine ekleyebilirsiniz :

    perl -i.bak -ne '/^HERE IT IS/ || print' file        
    
  • (G) awk

    awk '!/^HERE IT IS/' file > newfile
    

    GNU'nun awk( awkLinux'ta varsayılan ) daha yeni sürümleri (4.1.1 ve üstü) dosyayı yerinde de düzenleyebilir:

    gawk -i inplace  '!/^HERE IT IS/' file
    
  • Kabuk ( bash, zsh, ksh, muhtemelen diğerleri). Bu tür saçma olsa arasında öyle olabilir yapılabilir ancak diğer araçlar iyidir.

    while IFS= read -r line; do 
      [[ $line =~ ^"HERE IT IS" ]] || printf "%s\n" "$line"
    done < file > newfile
    

1
Sadece gösteriş yapıyorsun! ;-) (ama bir oylama aldınız, çünkü akıllı ve çok şey öğrendim ve bashbiri beni LOL yaptı)
Fabby

bash kişi kullanmalıdır printf "%s\n" "$line": beyaz boşlukları korumak için $ satırından alıntı yapmak ve bazı yankı problemlerinden kaçınmak (özel karakterleri yorumlamak vb.). ve ekleme ihtiyacını ortadan kaldırır --.
Olivier Dulac

@OlivierDulac yeterince adil. Saçak vakaları için işleri karmaşıklaştırmak istemedim ama Cuanglm eklediğinden IFS=ve sonuna -rkadar gidip sağlamlaştırabilirim .
terdon

@terdon: her şey daha iyi iyi ^^ için (ve yeni başlayanlar için çok bilgilendirici olduğu için zaten +1 yaptım)
Olivier Dulac

2
@OlivierDulac Unix & Linux'ta yayınlasaydım printf, IFS =, -r ve quoting :) kullanacağımı garanti edebilirim . Çoğu zaman komut satırından daha az rahat olan AU kitlesi için işleri basitleştiririm.
terdon

13

grepOnları filtrelemek için kullanırdım . Örneğin :

grep -v "^HERE IT IS" infile > outfile

Daha sonra dosyayı doldurmak için geri taşıyın.


Akıllı düşünme
Anwar

5

sed kesinlikle gitmenin yolu.

@Heemayl komutunun bu küçük değişikliği, desen referansındaki I nedeniyle aynı durumun kalıpta kullanılıp kullanılmadığını siler.

sed -i '/HERE IT IS/Id' <file>

Eğer bir dizinde bunu yapmak istediğiniz birkaç dosya varsa, onu böyle bul ile birleştirebilirsiniz.

find . -maxdepth 1 -type f -exec sed -i.bak '/HERE IT IS/Id' {} +

Maxdepth seçeneği, bunun dizinlere geri çekilmeyeceği anlamına gelir.


4

Başka bir python seçeneği:

#!/usr/bin/env python3
[print(l, end = "") for l in open(f).readlines() if not l.startswith("HERE IT IS")]

Burada f, tırnak işaretleri arasındaki dosyanın yoludur.


4

grep

grep -P '^(?!HERE IT IS)' file

(?!HERE IT IS)Normal ifade motorunu, yalnızca dizeyle takip edilmiyorsa tüm satır başlangıç ​​sınırıyla ( genellikle eşleşir^ ) eşleşecek şekilde yapan negatif ileriye dönük iddiaHERE IT IS

piton

#!/usr/bin/python3
import sys
fil = sys.argv[1]
with open(fil) as f:
    for line in f:
        if not line.startswith('HERE IT IS'):
            print(line, end="")

Komut dosyasını bir dosyaya kaydedin, deyin script.pyve terminaldeki aşağıdaki komutla çalıştırın.

python3 script.py infile

orada regex kullanabilirsiniz [print(l, end = "") for l in open(fil).readlines() if not re.match("HERE IT IS", l)], ama daha verimli değil startswith. [print(l, end = "") for l in open(f).readlines() if not l.startswith("HERE IT IS")]Çıktıyı bir listede nasıl üretmeyeceğini merak ettim .
Avinash Raj

İlk defa karşılaştığımda bana garip geldi. Tanımlanan listedeki tüm öğeler için bir yazdırma komutu (veya bununla yapmak istediğiniz herhangi bir eylem) oluşturur.
Jacob Vlijm


1

Vim'i Ex modunda kullanabilirsiniz:

ex -sc 'g/^HERE IT IS/d' -cx file
  1. g küresel arama

  2. d silmek

  3. x kaydet ve kapat

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.