Sed - eşleşen bir satırdaki bir karakteri yerinde mi değiştireceksiniz?


21

Bunun gibi satırlar içeren bir dosyada:

# lorem ipsum blah variable

#Yerinde belirli bir dize içeren aynı satırdaki karakteri (yorum) kaldırmak istiyorum . Bunun sediçin iyi mi?

Bu şartlı çalışmayı sağlamak için uğraşıyorum. Bunu yapmanın "beceriksiz" bir yolum var; Eşleşen satır numarasını awkveya ile bulabilir sedve sonra bu sayıyı ayrı bir sedkomutta kullanabilirim, ancak bunun çok daha iyi bir şekilde yapılabileceğine inanıyorum.

Yanıtlar:


36

Üzerinde çalışılacak hatların seçici olarak aradığınız dizeyi kullanın:

sed '/ipsum/s/#//g'

/ipsum/"ipsum" içeren satırları seçer ve yalnızca bu satırlarda izleyen komut (lar) yürütülür. Daha fazla komut çalıştırmak için kaşlı ayraç kullanabilirsiniz

/ipsum/{s/#//g;s/@/-at-/g;}

4
Katılıyorum; bu en iyi cevaptır (tek cevap olmasa da). Yorumlar: (1) 's/#//g'kaldıracaktır tüm# çizgi karakterleri. İstediğiniz bu değilse g("global" anlamına gelen) simgesini kaldırın . (2) Bir dosyayı yerinde düzenlemek için (soruda istendiği gibi) kullanın sed -i.
G-Man, 'Monica'yı Eski

2
(3) Gerçek dünyadaki durumlardan dolayı, bir satırın yorumunu kaldırmak isterseniz sed -i '/ipsum/s/#[[:space:]]*//', hemen ardından gelen boşluklardan ve sekmelerden kurtulmak için kullanmak isteyebilirsiniz #. (4) Ayrıca #, satırdaki ilk boş olmayan karakter olduğunu doğrulamayı da düşünebilirsiniz . Geçerli komut #satırdan siler prompt "Enter # of ipsums:".
G-Man, 'Monica'yı Yeniden Başlat' diyor

1
@ G-Man - harika bir ek! 2. pt'nize (lider alan), ne olacak: sed -i '/ipsum/s/^#[[:space:]]*//'?! ( ^satır $sonu için satır başlangıcı anlamına gelir ) - en azından gnu sed ...
Jeremy Davis

1
@JeremyDavis: Evet, olabilir doğrultusunda başlangıcına regex demirlemek ^, ama bu yanlış olur. Sık sık girintili kod #hemen kod önce koyarak yorum , bu yüzden #girintili. Bunu yapan tek kişi olduğumdan şüpheliyim.
G-Man

1
@ G-Man - ah evet, elbette! Teşekkürler, bunu düşünmemiştim. Ayrıca arasındaki boşluk kontrol etmek istediğimiz Yani ^& #daha böyle bir şey bu yüzden,: /ipsum/{/^[[:space:]]*#/s/#[[:space:]]*//}. O zaman bile, nerede olduğuna bağlı olarak #, yine de sorunlara neden olabilir (örn. Boşluk girintisi / ayrımı kullanan dillerde).
Jeremy Davis

7
$ cat input.txt
# lorem ipsum blah variable
# lorem ipsum blat variable
# lorem ipsum blow variable
# lorem ipsum blip variable
# lorem ipsum blue variable

sonra:

$ sed 's|# \(.*blue.*\)|\1|' input.txt

verir:

# lorem ipsum blah variable
# lorem ipsum blat variable
# lorem ipsum blow variable
# lorem ipsum blip variable
lorem ipsum blue variable

Aşağıdaki gibi çalışır:

sSöyler sedo düzenli ifade ne bulursa yerine gerektiğidir.

Desen şu şekilde # \(.*blue.*\)parçalanır: Bir karma ve ardından bir boşluk bulun. Köşeli ayraç ( \() gruplandırmayı başlatır. .*blue.*kelimeblue şeyden önce ve sonra . Sonraki parantez ( \)) gruplandırmayı kapatır.

Değiştirme, \1ilk gruplama braketinin içeriğine geri başvuru niteliğindedir.


3

Vim'i Ex modunda kullanabilirsiniz:

ex -sc '/ipsum/s/#//|x' file
  1. s vekil

  2. x kaydet ve kapat


Bu oldukça havalı. Bunu bilmiyordum! TBH, bu soru için en iyi cevap olduğundan emin değilim (IMO'nun önde gelen sed yanıtı) ama yine de çok havalı! Gönderdiğiniz için teşekkürler.
Jeremy Davis
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.