Yorumları görmezden gelen dosyalar nasıl dağılır (# ile başlayan satırlar)?


55

Paketleme yöneticisinin orijinali ve kendim tarafından değiştirilmiş özelleştirilmiş biri olan iki yapılandırma dosyasını hazırladım. Davranışı açıklamak için bazı yorumlar ekledim.

diffYorumları atlayarak yapılandırma dosyalarını nasıl çalıştırabilirim ? Yorumlanan bir satır şu şekilde tanımlanır:

  • isteğe bağlı önde gelen boşluk (sekmeler ve boşluklar)
  • karma işareti ( #)
  • başka bir karakter

İlk gereksinimi atlayan (en basit) düzenli ifade olacaktır #.*. GNU diff 3.0'ın --ignore-matching-lines=RE( -I RE) seçeneğini denedim , ancak o RE ile çalışmasını sağlayamadım. Ben de denedim .*#.*ve .*\#.*şans olmadan. Kelimenin tam anlamıyla (( Port 631) satırını REhiçbir şeyle eşleşmeyen şekilde koymak, RE'yi eğik çizgiler arasına koymak da yardımcı olmaz.

“Diff” aracında önerildiği gibi, regex'in tadı eksik mi? Denedim grep -G:

grep -G '#.*' file

Bu, yorumlarla eşleşiyor gibi görünüyor, ancak işe yaramadı diff -I '#.*' file1 file2.

Peki, bu seçenek nasıl kullanılmalı? diffBazı satırları nasıl atlayabilirim (benim durumumda, yorumlar)? Lütfen grepdosyayı önermeyi ve geçici dosyaları karşılaştırmayı önermeyin .


12
-ISeçenek bir blok halinde göz ardı edilmesine neden olur bütün onun satırları Regexp'i eşleşir. Böylece, yalnızca yorum yapmayan bir değişikliği görmezden gelebilirsiniz, ancak yorum yapmayan bir değişikliğe yakın olan yorum değişikliklerini değil.
Gilles 'SO- kötü olmayı durdur' 14

@Gilles: Teşekkürler, şimdi anladım neden diff -Ibeklediğim gibi davranmıyor. Cevabımı bu davranışı benim için netleştiren bir örnekle güncelledim.
Lekensteyn

Yanıtlar:


49

Gilles'a göre, -Iseçenek yalnızca bu kümenin içinde, eşleşmesi dışında başka hiçbir şey eşleşmediğinde bir çizgiyi yoksayar -I. Test edene kadar tam olarak alamadım.

Test

Testime üç dosya katılıyor:
Dosya test1:

    text

Dosya test2:

    text
    #comment

Dosya test3:

    changed text
    #comment

Komutlar:

$ # comparing files with comment-only changes
$ diff -u -I '#.*' test{1,2}
$ # comparing files with both comment and regular changes
$ diff -u -I '#.*' test{2,3}
--- test2       2011-07-20 16:38:59.717701430 +0200
+++ test3       2011-07-20 16:39:10.187701435 +0200
@@ -1,2 +1,2 @@
-text
+changed text
 #comment

Alternatif yol

-ISeçeneğin nasıl doğru bir şekilde kullanıldığını açıklayan bir cevap olmadığı için , bash mermilerinde çalışan bir alternatif sunacağım:

diff -u -B <(grep -vE '^\s*(#|$)' test1)  <(grep -vE '^\s*(#|$)' test2)
  • diff -u - birleşik fark
    • -B - boş satırları yoksay
  • <(command)- komut için bir dosya tanımlayıcısı açan, işlem değiştirme adı verilen bir bash özelliği , bu geçici bir dosyaya duyulan ihtiyacı ortadan kaldırır
  • grep - bir desenle eşleşen satırları yazdırma (değil) komutu
    • -v - eşleşmeyen satırları göster
    • E - genişletilmiş düzenli ifadeler kullanın
    • '^\s*(#|$)' - yorum ve boş satırlarla eşleşen düzenli ifade
      • ^ - çizginin başlangıcını eşleştir
      • \s* - eğer varsa boşlukla (sekmeler ve boşluklar) eşleş
      • (#|$) bir karma işareti ile eşleştirin veya alternatif olarak bir çizginin sonunu

6

Deneyin:

diff -b -I '^#' -I '^ #' file1 file2

Lütfen regex'in her iki dosyadaki karşılık gelen çizgiyle eşleşmesi gerektiğini ve çalışmak için ipliğin içindeki her değiştirilen çizgiyle eşleştiğini unutmayın, aksi halde yine de farkı gösterir.

Deseni kabuk genişlemesinden korumak ve regex ile ayrılmış karakterlerden (örneğin parantezler) kaçmak için tek tırnaklar kullanın.

diffutilsManuel olarak okuyabiliriz :

Bununla birlikte, -Iyalnızca normal ifadeyi içeren satırların eklenmesi veya silinmesi, hunk'ta değiştirilen her satır (her ekleme ve her silme) normal ifadeyle eşleşiyorsa yok sayar.

Başka bir deyişle, göz ardı edilmeyen her değişiklik için, göz diffardı edilenler de dahil olmak üzere çevresindeki tüm değişikliklerin bir listesini yazdırır. Birden fazla -Iseçenek kullanarak yoksayılacak satırlar için birden fazla normal ifade belirleyebilirsiniz . diffverilen her son satırdan başlayarak her satırı her normal ifadeyle eşleştirmeye çalışır.

Bu davranış, burada ayrıca armel tarafından da açıklanmaktadır .

İlgili: Tüm yorumları görmezden gelen bir fark nasıl yapabilirim?


2

İnternette arama yaptıktan sonra Lekensteyn'in alternatif yolu bulduğum en iyisi.

Ama ben dif çıktısını yama olarak kullanmak istiyorum ... ve bir sorun var çünkü satır numarası "grep -v" nedeniyle tutulur.

Bu yüzden bu komut satırını iyileştirmeyi amaçlıyorum:

diff -u -B <(sed 's/^[[:blank:]]*#.*$/ /' file1)  <(sed 's/^[[:blank:]]*#.*$/ /' file2)

Mükemmel değil ama satır numarası yama dosyasında tutulur.

Bununla birlikte, yorum satırı yerine yeni bir satır eklenirse ... yorum, aşağıda gördüğümüz gibi düzeltme eki eklerken YARALANMIŞ bir Hunk üretecektir.

File test1:
  text
  #comment
  other text
File test2:
  text
  new line here
  #comment changed
  other text changed

şimdi test bizim komutumuz

$ echo -e "#!/usr/bin/sed -f\ns/^[[:blank:]]*#.*$/ /" > outcom.sed
$ echo "diff -u -B <(./outcom.sed \$1)  <(./outcom.sed \$2)" > mydiff.sh
$ chmod +x mydiff.sh outcom.sed
$ ./mydiff.sh file1 file2 > file.dif
$ cat file.dif
--- /dev/fd/63  2014-08-23 10:05:08.000000000 +0200
+++ /dev/fd/62  2014-08-23 10:05:08.000000000 +0200
@@ -1,2 +1,3 @@
 text
+new line

-other text
+other text changed

/ dev / fd / 62 & / dev / fd / 63 işlem ikamesiyle üretilmiş dosyalardır. "+ Yeni satır" ve "Diğer metin" arasındaki satır, yorumların yerine sed ifademizde tanımlanan varsayılan boşluk karakteridir.

Ve şimdi, bu yamayı uyguladığımızda neler geliyor:

$ patch -p0 file1 < file.dif 
patching file file1
Hunk #1 FAILED at 1.
1 out of 1 hunk FAILED -- saving rejects to file file1.rej

Çözüm, -u olmadan birleştirilmiş diff formatını kullanmamaktır.

$ echo "diff -B <(./outcom.sed \$1)  <(./outcom.sed \$2)" > mydiff.sh
$ ./mydiff.sh file1 file2 > file.dif
$ cat file.dif
1a2
> new line
3c4
< other text
---
> other text changed
$ patch -p0 file1 < file.dif 
patching file file1
$ cat file1
text
new line
#comment
other text changed

Şimdi yama dosya çalışma dosyası (çok karmaşık fark sürecinde sonuç garantisi olmadan).


Birleşik farkınız içerik farklılıkları nedeniyle başvuruda başarısız olur. İçeriği diff -U0 one twodevre dışı bırakmak için kullanabilirsiniz . Yama için, kdiff3 gibi daha uygun olabilecek birçok araç vardır.
Lekensteyn

-U0Bağlamı devre dışı bırakma seçeneği için teşekkür ederiz . Not: kdiff3 grafiksel bir araçtır. Git birleştirme niteliklerini yönetmek için otomatik araca ihtiyacım var.
syjust,

vimdiffÜç yollu birleştirmeleri destekler, bakmaya değer olabilir.
Lekensteyn

Daha kesin olmak gerekirse, git birleştirme işlemini bir sql betiğinde exludes ile otomatikleştirmek için bir betik aracına ihtiyacım var. kdiff3 ve vimdiff benim durumumda kullanılamayacak etkileşimli araçlardır.
syjust,

1

Genelde bu dağınıklığı görmezden gelirim:

  • grep -v "^#" | cat -sBunları kullanarak ve farklılaştırarak yorumlanmamış sürümler oluşturma veya ...
  • vim -dDosyalara bakmak için kullanma . Sözdizimi vurgulama, yorum yapmamaya karşın yorum dışı farklılıkları oldukça belirgin hale getirir. Satır içi farkın farklı şekilde vurgulanması, hangi değerlerin veya değerlerin bir bakışta değiştirildiğini görebilmenizi sağlar, bunu favorim yapar.

0

İşte yorumlanan tüm satırları kaldırmak için kullanıyorum - bir sekme veya boşlukla başlayanlar bile - ve boş olanları:

egrep -v "^$|^[[:space:]]*#" /path/to/file

ya da yapabilirsin

sed -e '/^#.*/d' -e 's/#.*//g' | cat -s
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.