it-swarm-tr.com

Yorumları yok sayan dosyalar (# ile başlayan satırlar) nasıl fark edilir?

Paket konfigürasyonundan orijinal ve kendim tarafından değiştirilmiş özelleştirilmiş bir dosya olmak üzere iki yapılandırma dosyam var. Davranışı tanımlamak için bazı yorumlar ekledim.

Yorumları atlayarak yapılandırma dosyalarında diff komutunu nasıl çalıştırabilirim? Yorum yapılan 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 şey

İlk gereksinimi atlayan (en basit) normal ifade #.* Olacaktır. GNU diff 3.0 --ignore-matching-lines=RE (-I RE) Seçeneğini denedim, ancak bu RE ile çalışmayı alamadım. Ayrıca .*#.* Ve .*\#.* Şanssız. Satırı (Port 631) RE olarak koymak hiçbir şeyle eşleşmez, RE'yi eğik çizgiler arasına koymak da yardımcı olmaz.

“diff” aracının normal ifadesinin lezzeti eksik gibi görünüyor mu? , grep -G:

grep -G '#.*' file

Bu yorumlarla eşleşiyor gibi görünüyor, ancak diff -I '#.*' file1 file2 İçin çalışmıyor.

Peki, bu seçenek nasıl kullanılmalıdır? diff 'ın belirli satırları atlamasını nasıl sağlayabilirim (benim durumumda, yorumlar)? Lütfen greping dosyasını önermeyi ve geçici dosyaları karşılaştırmayı önermeyin.

56
Lekensteyn

Gilles'e göre, -I Seçeneği yalnızca bu set içindeki hiçbir şey -I Eşleşmesi dışında eşleşmezse bir satırı yok sayar. Test edene kadar tam olarak alamadım.

Test

Testime üç dosya dahil:
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

Şimdiye kadar -I Seçeneğinin nasıl doğru kullanılacağını açıklayan bir cevap olmadığından, bash kabuklarında ç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ı açan süreç değiştirme adlı bir bash özelliği, geçici bir dosyaya olan ihtiyacı ortadan kaldırır
  • grep - bir desenle eşleşen satırları yazdırma komutu (değil)
    • -v - eşleşmeyen satırları göster
    • E - genişletilmiş normal ifadeler kullanın
    • '^\s*(#|$)' - yorumlar ve boş satırlarla eşleşen normal bir ifade
      • ^ - bir satırın başıyla eşleşir
      • \s* - varsa boşlukla (sekmeler ve boşluklarla) eşleşir
      • (#|$) Bir karma işaretiyle veya alternatif olarak bir satırın sonuyla eşleşiyor
54
Lekensteyn

Deneyin:

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

Normal ifadenin her iki dosyadaki karşılık gelen çizgiyle eşleşmesi gerektiğini ve çalışmak için iri parçadaki her değiştirilen çizgiyle eşleştiğini lütfen unutmayın, aksi takdirde yine de farkı gösterecektir.

Deseni Kabuk genişlemesinden korumak ve normal rezerve edilmiş karakterlerden (örn. Köşeli ayraçlar) kaçmak için tek tırnak kullanın.

diffutils el kitabında okuyabiliriz:

Ancak, -I, Yalnızca, yığın içindeki her değiştirilen satır (her ekleme ve her silme) normal ifadeyle eşleşiyorsa, normal ifadeyi içeren satırların eklenmesini veya silinmesini yoksayar.

Başka bir deyişle, cahil olmayan her değişiklik için diff, cahil olanlar da dahil olmak üzere çevresindeki tüm değişiklik kümesini yazdırır. Birden fazla -I Seçeneğini kullanarak satırların yoksayması için birden fazla normal ifade belirtebilirsiniz. diff, her satırı verilen son ifadeden başlayarak her normal ifadeyle eşleştirmeye çalışır.

Bu davranış burada armel ile de iyi açıklanmıştır.

İlgili: Tüm yorumları yok sayan bir fark nasıl yapabilirim?

7
kenorb

Web'de arama yaptıktan sonra, Lekensteyn'in alternatif yolu bulduğum en iyisi.

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

Bu yüzden bu komut satırını geliş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.

Ancak, yorum satırı yerine yeni bir satır eklenirse ... yorum, aşağıda gördüğümüz gibi yamalama yaparken bir Hunk FAILED üretecektir.

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

şimdi test et 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 ikamesi ile üretilen dosyalardır. "+ Yeni satır" ve "-diğer metin" arasındaki satır, açıklamaların yerini almak için sed ifademizde tanımlanan varsayılan boşluk karakteridir.

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

$ 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şik fark biçimini 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 dosyası çalışma dosyası (sonuç garantisi olmadan çok karmaşık fark süreci).

3
syjust

Ben genellikle bu dağınıklığı ya görmezden:

  • grep -v "^#" | cat -s Kullanarak yorumlanmamış sürümler oluşturuluyor ve bunlar farklı veya ...
  • Dosyalara bakmak için vim -d Kullanın. Sözdizimi vurgulaması, yorum ve farklılıklar arasındaki farkları belirgin hale getirmeye özen gösterir. Satır içi farkın farklı şekilde vurgulanması, hangi değerlerin veya değerlerin bir bakışta değiştirildiğini görebilmeniz, bunu en sevdiğim yapar.
1
Caleb

İşte tüm yorum satırları -bir sekme veya boşluk ile başlayanlar- ve boş olanları kaldırmak için kullandığım şey:

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

ya da yapabilirsin

sed -e '/^#.*/d' -e 's/#.*//g' | cat -s
0
Philomath