Windows Powershell'de iki metin dosyasını nasıl ayırt edebilirim?


96

İki metin dosyasına sahibim ve Windows Powershell'i kullanarak aralarındaki farkları bulmak istiyorum. Mevcut Unix diff aracına benzer bir şey var mı? Yoksa göz önünde bulundurmadığım başka bir yol var mı?

Compare-object'ı denedim, ancak şu şifreli çıktıyı aldım:

PS C:\> compare-object one.txt two.txt

InputObject                                                 SideIndicator
-----------                                                 -------------
two.txt                                                     =>
one.txt                                                     <=

Yanıtlar:


101

Kendim anladım. Powershell, metin yerine .net nesneleriyle çalıştığından, metin dosyalarının içeriğini göstermek için get-content kullanmanız gerekir. Bu yüzden, soruda yapmaya çalıştığım şeyi yapmak için şunu kullanın:

compare-object (get-content one.txt) (get-content two.txt)

1
İki dosyayı karşılaştırmaya çalıştığımda çok şaşırmıştım: sıralanmamış bir sayı dizisi ve bunları sıraladıktan sonra aynı sayı dizisi. Dosyaların çok farklı olmasına rağmen çıktı yok. Görünüşe göre compare-object düzeni dikkate almıyor.
cgmb

1
@cgmb - Bunu -SyncWindow 0düzeltmek için kullanabilirsiniz , inanıyorum, ancak henüz yeni tanıtıldığından emin değilim. Yine de bu konuda akıllıca değil.
James Ruskin

32

Bunu yapmanın daha basit bir yolu yazmaktır:

diff (cat file1) (cat file2)

16
Diff ve cat sadece PowerShell'deki Compare-Object ve Get-Content içeriklerinin takma adlarıdır. Aynı şey.
Shawn Melton

4
bu kabul edilen cevapla aynı olmasına rağmen, bu sözdizimini daha fazla kullanmayı seviyorum
Elijah W. Gagne

diffBuradaki diğer cevaplar gibi hiçbir şekilde * nix gibi davranmadığını unutmayın. Yerine daha karmaşık bir ifade kullandığımda catyanlış çıktı aldım, bu yüzden * nix'ten gelirseniz bunu PowerShell'de yapmaktan kaçınmak için başkalarına tavsiye edeceğim.
Nickolay

29

Veya bu şekilde DOS fckomutunu kullanabilirsiniz (Bu, her iki dosyanın çıktısını gösterir, böylece farklılıkları taramanız gerekir):

fc.exe filea.txt fileb.txt > diff.txt

fcFormat-Custom cmdlet'ine bir takma ad olduğundan, komutu komut olarak girdiğinizden emin olunfc.exe . Lütfen birçok DOS yardımcı programının UTF-8 kodlamasını işlemediğini unutmayın.

Ayrıca bir CMD işlemi doğurabilir ve fciçinde koşabilirsiniz .

start cmd "/c  ""fc filea.txt fileb.txt >diff.txt"""

Bu, PowerShell'e tırnak işaretleri içindeki parametreleri kullanarak 'cmd' programıyla bir işlem başlatmasını söyler. Tırnak içinde, komutu çalıştırmak ve sonlandırmak için '/ c' cmd seçeneğidir. İşlemde cmd ile çalıştırılacak olan asıl komut fc filea.txt fileb.txtçıktıyı dosyaya yönlendirmektir diff.txt.

DOS'u fc.exepowershell içinden kullanabilirsiniz .


2
DOS'u getirmek için +1 ^ _ ^
Jeff Bridgman

1
"fc" benim için çalışmıyordu ve Format-Custom'dan ayırt etmek için "fc.exe" olarak belirtmem gerektiğinin farkında değildim. Tam olarak aradığım şeydi. Teşekkürler.
Xonatron

Belki de tam bir filistinim ama bu bana daha kullanışlı geliyor. Sorunumu çok güzel bir şekilde çözdü.
AJ.

Tek sorun bu HATES unicode'dur.
iCodeSometime

7

diff on * nix, kabuğun bir parçası değil, ayrı bir uygulama.

PowerShell altında diff.exe'yi kullanamamanızın herhangi bir nedeni var mı?

UnxUtils paketinden bir sürüm indirebilirsiniz ( http://unxutils.sourceforge.net/ )


10
PowerShell şimdi dahil olduğundan, indirilecek ve yüklenecek hiçbir şey yoktur.
Bratch

Kullanmıştım git diffçünkü zaten kurmuştum . Ne beklediğim çıktı fc.exene Compare-Objectüretti.
Raziel

4

compare-object (aka diff alias), bir unix diff gibi bir şey yapmasını beklediğiniz takdirde acıklıdır. Diff (gc file1) (gc file2) denedim ve bir satır çok uzunsa, fiili diff'i göremiyorum ve daha da önemlisi, diff'in hangi satır numarasının açık olduğunu söyleyemiyorum.

-Passthru eklemeyi denediğimde, şimdi farkı görebiliyorum, ancak farkın hangi dosyada olduğunu kaybediyorum ve hala satır numarası alamıyorum.

Tavsiyem, dosyalardaki farklılıkları bulmak için powershell kullanmayın. Bir başkasının da belirttiği gibi, fc kıyaslama nesnesinden biraz daha iyi çalışır ve çalışır, hatta Mikeage'nin bahsettiği unix emülatörü gibi gerçek araçları indirip kullanır.


Ayrıca -SyncWindowvarsayılan olarak maxint olduğu gibi bir küme karşılaştırması (yani sırayı görmezden gelme) yapıyor gibi görünmektedir. Bunu 0'a ayarlamak onu da yapmaz diff... Ve bir boruyu (... | select-object ...)giriş olarak geçirdiğimde saçma sapan bir şeydi , ben de vazgeçtim.
Nickolay

3

Diğerlerinin de belirttiği gibi, eğer bir unix-y diff çıktısı bekliyorsanız, powershell diff takma adını kullanmak sizi üzecektir. Birincisi, dosyaları okumak için elini tutmanız gerekir (gc / get-content ile). Bir diğeri için, fark göstergesi içerikten uzakta, sağda - okunabilirlik kabusu.

Aklı başında bir çıktı arayan herkes için çözüm

  1. gerçek bir fark olsun (örneğin, GnuWin32'den)
  2. düzenleme% USERPROFILE% \ Documents \ WindowsPowerShell \ Microsoft.PowerShell_profile.ps1
  3. satırı ekle

    remove-item alias:diff -force

-Force argümanı gereklidir, çünkü Powershell bu özel yerleşik takma ad konusunda oldukça değerlidir. Herhangi biri ilgileniyorsa, GnuWin32'yi kurduktan sonra, powershell profilime aşağıdakileri de ekliyorum:

remove-item alias:rm
remove-item alias:mv
remove-item alias:cp

Esasen Powershell birlikte yürütülen ve yazılan argümanları anlamadığından, örneğin "rm -Force -Recurse", "rm -rf" den çok daha fazla çaba gösterir.

Powershell bazı güzel özelliklere sahip, ancak benim için yapmamayacağı bazı şeyler var.


2

WinMerge , GUI tabanlı başka bir iyi diff aracıdır.


1
Geçmişte böyle yaptım, ki bu küçük bir senaryo ile değiştirmek istediğim manuel bir süreç.
Bratch

1

Bir GUI diff arayüzü sağlayan Windiff de var (GUI tabanlı CVS / SVN programları ile kullanım için mükemmel)


1

fc.exe* nix diff gibi çalışmak üzere tasarlandığından metin karşılaştırması için daha iyidir, yani satırları sıralı olarak karşılaştırır, gerçek farklılıkları gösterir ve yeniden senkronize etmeye çalışır (eğer farklı bölümler farklı uzunluklarda ise). Ayrıca bazı yararlı kontrol seçeneklerine (metin / ikili, büyük / küçük harf duyarlılığı, satır numaraları, yeniden senkronizasyon uzunluğu, uyumsuzluk arabellek boyutu) sahiptir ve çıkış durumu sağlar (-1 hatalı sözdizimi, 0 dosya aynı, 1 dosya farklı, 2 dosya eksik). (Çok) eski bir DOS yardımcı programı olduğundan, birkaç sınırlaması vardır. En önemlisi, otomatik olarak Unicode ile çalışmaz, ASCII 0 MSB karakterini bir satır sonlandırıcı olarak kabul eder, böylece dosya 1 karakter satırlık bir sıra haline gelir (@kennycoc: BOTH dosyalarının Unicode, WinXP kullanılacağını belirtmek için / U seçeneğini kullanın) ) ayrıca 128 karakterlik (128 bayt ASCII,)

compare-object, 2 nesnenin üye olarak aynı olup olmadığını belirlemek için tasarlanmıştır. nesneler koleksiyon ise o zaman SETS (işlem karşılaştırması-nesnesine bakınız), yani yinelenmemiş UNORDERED koleksiyonlar olarak kabul edilir. Sipariş veya kopyalardan bağımsız olarak aynı üye öğelerine sahiplerse 2 takım eşittir. Bu, metin dosyalarının farklılıklarla karşılaştırılmasında yararını ciddi şekilde sınırlandırır. İlk olarak, varsayılan davranış tüm nesnenin (dosya = dizelerin dizisi) tamamı kontrol edilinceye kadar farkları toplar, böylece farkların konumu ile ilgili bilgileri kaybeder ve hangi farkların eşleştirildiğini belirlemez (ve bir SET için satır numarası kavramı yoktur) dizeleri -Synchwindow 0 kullanmak, farklılıkların ortaya çıktıkça yayılmasına neden olur, ancak bir dosyanın fazladan bir satırı varsa, ardından başka bir satır aynıysa bile sonraki satır karşılaştırmaları başarısız olabilir (bir telafi edici oluncaya kadar) diğer dosyadaki fazladan satır, böylece eşleşen satırları yeniden hizalar). Bununla birlikte, powershell son derece çok yönlüdür ve bu işlevselliği kullanarak, önemli karmaşıklık pahasına ve dosyaların içeriğinde bazı kısıtlamalar olsa da yararlı bir dosya karşılaştırması yapılabilir. Metin dosyalarını uzun (> 127 karakter) satırlarla ve satırların çoğunlukla 1 ile eşleştiği yerde karşılaştırmanız gerekirse:

diff (gc file1 | % -begin { $ln1=0 } -process { '{0,6}<<:{1}' -f ++$ln1,$_ }) (gc file2 | % -begin { $ln2=0 } -process { '{0,6}>>:{1}' -f ++$ln2,$_ }) -property { $_.substring(9) } -passthru | sort | out-string -width xx

xx en uzun satırın uzunluğu + 9

açıklama

  • (gc file | % -begin { $ln=0 } -process { '{0,6}<<:{1}' -f ++$ln,$_ }) Dosyanın içeriğini alır ve difere geçirmeden önce satır numarasını ve dosya göstergesini (<< veya >>) her satıra (format string operatörünü kullanarak) hazırlar.
  • -property { $_.substring(9) }diff'e, ilk 9 karakteri görmezden gelen (satır numarası ve dosya göstergesi olan) her nesne çiftini karşılaştırmasını söyler. Bu, bir özellik adı yerine hesaplanmış bir özellik (bir komut dosyası bloğunun değeri) belirtme özelliğini kullanır.
  • -passthru farklı karşılaştırılan nesneler yerine (farklı olan) giriş nesnelerinin (satır numarasını ve dosya göstergesini içeren) çıkarmasına neden olur.
  • sort-objectsonra tüm satırları tekrar sıraya sokar.
    out-string, kesilmeyi önleyecek kadar büyük bir genişlik belirleyerek ekran genişliğine (Marc Towersap tarafından belirtildiği gibi) uyacak şekilde varsayılan kesmeyi durdurur. Normalde, bu çıktı daha sonra bir kaydırma editörü (örneğin not defteri) kullanılarak görüntülenen bir dosyaya yerleştirilir.

Not

{0,6} satır numarası, haklı, boşlukla doldurulmuş 6 karakterli satır numarasını (sıralama için) verir. Dosyaların 999.999'dan fazla satırı varsa, daha geniş olacak şekilde formatını değiştirin. Bu aynı zamanda $_.substringparametrenin (satır numarası genişliğinden 3 daha fazla) ve out-xx değerinin (maksimum satır uzunluğu + $_.substringparametre) değiştirilmesini gerektirir.

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.