Bir dosyadaki tüm yorumları nasıl silebilirim?


21

Yorumları içeren bir dosyam var:

foo
bar
stuff
#Do not show this...
morestuff
evenmorestuff#Or this

Sadece tüm uncommented kodunu yazdırmak istiyorum:

foo
bar
stuff
morestuff
evenmorestuff

Yorumları bir dosyadan çıkarabilmek çok önemlidir ... Bunu yapmanın iyi bir yolu nedir?


1
grep ile bir satırın bölümlerini kaldıramazsınız. bunun için sed kullanabilirsiniz
miracle173 24:14

2
Metniniz ve örneğiniz çelişiyor. Yorumlanan satırlar hakkında yazıyorsunuz, ancak son satırdan açıkça satır parçaları demek istediniz. Ve sonra EOL dahil olmak üzere yorumu olan ilk satır silinir ve ikinci saniye olabilir, ancak son satır olduğu açık değildir. Lütfen 'yorum yapılan satırları' kesin ve örneklerinizi netleştirmek için yeniden ifade edin.
Anthon

5
kullanmayı deneyin awk -F\# '$1!="" { print $1 ;} '.
Archemar

2
Gibi bir çizgi nasıl echo '#' # output a #ele alınır?
Kusalananda

3
@ Soru Sorgulama Ben akıllı olabilirim, ama bir kabuk-dilbilgisi-ayrıştırıcı zeki yazmıyorum.
Kusalananda

Yanıtlar:


40

Tüm yorumları kaldırmanın bir yolu seçeneği grepile kullanmaktır -o:

grep -o '^[^#]*' file

nerede

  • -o: çizginin yalnızca eşleşen kısmını yazdırır
  • ilk olarak ^: satır başı
  • [^#]*: #tekrarlanan sıfır veya daha fazla kez dışında herhangi bir karakter

Boş satırların da kaldırılacağını, ancak yalnızca boşluk içeren satırların kalacağını unutmayın.


2
Kullanacağımgrep -v '^#' file > newfilewithoutcomments
Basile Starynkevitch

1
Bunun, kabuk komut dosyaları için genel bir yöntem OLMADIĞINA dikkat edilmelidir, çünkü satır somvar='I am a long complicated string ## with special characters' # and I am a commentdoğru işlenmeyecektir.
Wildcard

Bu varyant benim için daha iyi çalışıyor (Mac'te):grep -o '^[^#].*' file
Pierz

Yorumlar gitti ama çıktı yerlerinde bir sürü beyaz boşluk görüyorum? sedçözüm sadece bir boş satır var, bir şey eksik sürece diğer cevap kullanmak için sağlam bir argüman gibi görünüyor?
JBallin

@JBallin grepBelki için bazı takma ad tanımladınız mı? Yine de örnek girişini grepgönderen command grepboşluklar görmeye çalışın .
jimmij

31

sedBundan daha iyi bir iş yapabileceğine inanıyorum grep. Bunun gibi bir şey:

sed '/^[[:blank:]]*#/d;s/#.*//' your_file

açıklama

  • sedvarsayılan olarak dosyalarınıza satır satır bakar ve dönüşümleri tırnak içine aldıktan sonra her satırı yazdırır. ( sed '' your_filedeğişmeden tüm satırları yazdırır).
  • Burada sedher satırda gerçekleştirmek için iki komut veriyoruz (bunlar noktalı virgülle ayrılmıştır).
  • İlk komut diyor: /^[[:blank:]]*#/d. İngilizce'de, bu, satırın başında bir karma ile eşleşmesi durumunda (herhangi bir sayıda önde gelen boşluktan önce gelirse), bu satırı silin (yazdırılmaz).
  • İkinci komut ise: s/#.*//. İngilizce'de, bir karma işaretini ve ardından bulabildiğiniz kadar çok şeyi (satırın sonuna kadar, yani) hiçbir şeyle değiştirmeyin (hiçbir şey son ikisi arasındaki boş alan değildir //).
  • Özetle, bu, tamamen yorumlardan oluşan dosya silme satırlarından geçecek ve bundan sonra kalan satırlar yorumların dışına çıkacaktır.

1
Ayrıca, bir dize içindeki karmadan sonra bulunan her şeyi siler , değil mi? Eg mystring="Hello I am a #hash" olacak mystring="Hello I am a"
javadba

@javadba, evet, ama bu noktada tam bir ayrıştırıcı da kullanabilirsiniz. Ne tırnak ve değişken atamaları anlayabiliyorum ama bu verileri kullanıyor gidiyor olamaz yorumlarınızı işlemek? (Bu nedenle crontab, önde gelen boşluklu veya boşluksuz tam satırlı yorumlara izin ver, ancak bir satırda sondaki yorumlara izin vermeme gibi birçok yapılandırma dosyası bu nedenle mantık ÇOK daha basittir. için bir crontab yorum striptizci.)
Wildcard

harika bir cevap, bu çok çeşitli genel kullanım durumları için büyük bir fayda ve karmaşıklık dengesine benziyor, ancak önceden (yalnızca #sütun 1'de) başlayan satırları silmeniz gerektiğini önceden biliyor olmanız durumunda , herhangi bir yararı yoktur sedover grep -v "^#"?
RBF06

4

Sed komutunu kullanarak gerekli çıktıyı elde edebilirsiniz. Aşağıdaki komut benim için hile yapmıştı.

sed 's/#.*$//g' FileName

Nerede

  • #.*$- Regexp #, satırın sonuna kadar başlayan tüm dizeleri filtreleyecektir

Burada bu satırları kaldırmamız gerekiyor, bu yüzden boş 'atlama' kısmı ile değiştirdik.

  • g - dosya sonuna ulaşılana kadar desenin tekrar tekrar arandığından bahsetmek.

Sed'in genel sözdizimi: s/regexp/replacement/flags FileName


2
Not: Bu durumda 4. satır yeni satırla değiştirilir.
αғsнιη

1
Bunu şu sedkomutu içeren bir komut dosyası ile deneyin ...
Kusalananda

Bu Kaldıramayacaksanprint "#tag" # Print a hashtag.
Ray Butterworth

3

Diğerlerinin de belirttiği gibi, sed'in ve diğer metin tabanlı araçların bir komut dosyasının herhangi bir kısmı yorum gibi görünüyor ancak aslında çalışmıyorsa iyi çalışmaz. Örneğin, bir dizenin içinde bir # veya oldukça yaygın olan $#ve öğesini bulabilirsiniz ${#param}.

Kod küçültme özelliği olan shfmt adlı bir kabuk biçimlendirici yazdım . Bu, diğer şeylerin yanı sıra yorumların kaldırılmasını içerir:

$ cat foo.sh
echo $# # inline comment
# lone comment
echo '# this is not a comment'
[mvdan@carbon:12] [0] [/home/mvdan]
$ shfmt -mn foo.sh
echo $#
echo '# this is not a comment'

Ayrıştırıcı ve yazıcı Go paketleridir, bu nedenle özel bir çözüm istiyorsanız, yorumları tam olarak istediğiniz şekilde kaldırmak için 20 satırlık bir Go programı yazmak oldukça kolay olmalıdır.


2

Ters çevirme eşleşmesini şu şekilde kullanabilirsiniz:

    #grep -v "#" filename

-v, --invert-match Eşleşmeyen çizgileri seçmek için eşleme duygusunu ters çevirin. (-v, POSIX tarafından belirtilir.)


2
@alinh Cevabı incelediğiniz için teşekkür ederiz. Sorunun yalnızca satırın başlangıcını değil, dosyanın herhangi bir yerini gerektirdiğini lütfen unutmayın. Bu aynı zamanda yukarıdaki soruda beklenen sonucunu da göstermektedir. Sadece hattın başlangıcını ararsam cevabım yanlış olur.
Raza

zzz. benim kötü, son satırı görmedim :(
alinh

1
Bu işlem evenmorestuffOP örneğinden başlayarak çizgiyi tamamen kaldıracaktır .
Joseph R.

@JosephR. İyi yakalama. Bunu daha önce özlemiştim. Bu durumda grep -o '^[^#]*' fileen iyi çözüm olacaktır. bu zaten jimmij tarafından açıklanmıştır. değerlendirmeniz için teşekkür ederiz
Raza

Bu Kaldıramayacaksanprint "#tag" # Print a hashtag.
Ray Butterworth

2

Ben joseph'ın cevabını seviyorum ama şerit // yorum da gerekiyordu, bu yüzden biraz değiştirdim & redhat üzerinde test

# no comments alias
alias nocom="sed -E '/^[[:blank:]]*(\/\/|#)/d;s/#.*//' | strings"

# example
cat SomeFile | nocom | less

Bahse girerim, boş satırları kaldırmak için dizeleri kullanmaktan daha iyi bir yol var ama kullandığım hızlı ve kirli bir çözümdü.

Şerefe


Bu Kaldıramayacaksanprint "#tag" # Print a hashtag.
Ray Butterworth


1
cat YOUR_FILE | cut -d'#' -f1

Kullandığı #sütun ayırıcı olarak ve sadece ilk sütunu (bundan önce her şeyi olduğu tutar #).


1
Eğer YOUR_FILEbu komutları içeren bir script, script bırakacaktı cat YOUR_FILE | cut -'o satırda dosyada.
Kusalananda

1

Şunun gibi ifadeyi kullan:

egrep -v "#|$^" <file-name> 

: -v: tersine eşleşecek

: #: # ile başlayan tüm satırlarla eşleşecek

: $ ^: tüm boş satırlarla eşleşecek


1
Hayır, #satırın herhangi bir yerinde eşleşecek ve tüm satırı kaldıracaktır.
ilkkachu

1

En iyi çözüm şu komutu kullanmak olacaktır:

sed -i.$(date +%F) '/^#/d;/^$/d' ntp.conf

-İ yerinde düzenleme ancak doğrudan takip eden önek sed'e bir yedek oluşturmasını söyler. Tarih uzantısına sahip bu durumda (ntp.conf.date) Her biri bir adres boşluğuna sahip iki komut çalıştırırız, birincisi yorumlanmış satırları siler ve ikincisi birinciden noktalı virgülle ayrılmış olarak boş satırları siler.

Ben bu çözümü buldum: theurbanpenguin.com


0

Diğer cevapların hiçbiri bu adaleti yapmıyor, ya boş satırlar halinde ya da yorumun ilk karakterde olmadığı satırlarda ayrılıyorlar. Bunu kullanarak sona erdi:

cat << EOF >> ~/.bashrc
alias nocom='sed -e "/^\s*#/d" -e "/^\s*$/d"'
EOF

Bu bir takma ad oluşturur, böylece ezberlemenize gerek kalmaz (bununla başlamak imkansızdır). Yeni bir oturum açın, yeni nocomkomutu alacaksınız . Sonra sadece

nocom /etc/foobar.conf

Şerefe.


1
.*$ilk normal ifadede eşleşmenin pek bir anlamı yoktur - çapa işe yaramaz ve değiştirilen metni kullanmak için eşleşen metni yakalamazsınız. sadece kullanın^\s*
Jeff Schaller

Bu Kaldıramayacaksanprint "#tag" # Print a hashtag.
Ray Butterworth

0

Joseph R.'ın 2. cevabından sonra, /^$/dboş satırı kaldırmak için ekliyorum .

sed '/^[[:blank:]]*#/d;s/#.*//;/^$/d'

-1

Benim için neyin işe yaradığını ve diğerlerini okuduktan sonra en mantıklı gibi görünen şeyleri açıklama ile gönderiyorum. Birkaç gönderi yaklaştı, ancak henüz yorum yapamadım (çünkü yeniyim):

grep -E -v "(^#.*|^$)" filename
  • -E = aşağıdaki kalıbı egrep kullanmaya benzer şekilde normal bir ifade olarak yorumlar
  • -v = desenin tersini yazdır (ifadeyle eşleşmeyen çizgiler yazdırılır)
  • "(^#.*|^$)"= bunun bir OR ifadesini belirten bir borusu vardır. Bu ifade, bir satırla başlayan #(ve ondan sonraki herhangi bir şey) VEYA satırın başı ile sonu arasında sıfır karakterli herhangi bir satır yazdırdığını söyler .

-vEkranda ile başlamaz karakterlerle herhangi bir satır olacak ters çevirmeyi, yazdırılacaktır #.


Bu Kaldıramayacaksanprint "#tag" # Print a hashtag.
Ray Butterworth

Ah, doğru ... elbette. Bunu işaret ettiğiniz için teşekkürler. Ben pam.d yapılandırmaları gibi tipik linux yapılandırma dosyaları ile ilgili bir cevap arıyordum, bu yüzden bunu düşünmedim. Sanırım kod ile aynı satırda bulunan yorumları bulmak ve kaldırmak için uyarlanması gerekir. Muhtemelen yukarıdaki özel sorunum için daha iyi bir çözüm gördüm: egrep -v "# | $ ^"
jackbmg
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.