it-swarm-vi.tech

Làm cách nào để tìm khác biệt hai tệp văn bản trong Windows Powershell?

Tôi có hai tệp văn bản và muốn tìm sự khác biệt giữa chúng bằng Windows Powershell. Có một cái gì đó tương tự như công cụ tìm khác biệt Unix có sẵn? Hay có một cách khác mà tôi chưa xem xét?

Tôi đã thử so sánh đối tượng, nhưng nhận được kết quả khó hiểu này:

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

InputObject                                                 SideIndicator
-----------                                                 -------------
two.txt                                                     =>
one.txt                                                     <=
104
Brian Willis

Tìm ra nó bản thân mình. Vì Powershell hoạt động với các đối tượng .net chứ không phải văn bản, bạn cần sử dụng nội dung get để hiển thị nội dung của tệp văn bản. Vì vậy, để thực hiện những gì tôi đã cố gắng làm trong câu hỏi, sử dụng:

compare-object (get-content one.txt) (get-content two.txt)
110
Brian Willis

Một cách đơn giản hơn để làm là viết:

diff (cat file1) (cat file2)
34
Alex Y.

Hoặc bạn có thể sử dụng lệnh DOS fc như vậy (Điều này hiển thị đầu ra của cả hai tệp để bạn sẽ phải quét tìm sự khác biệt):

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

fc là bí danh cho lệnh ghép ngắn Format-Custom, vì vậy hãy chắc chắn nhập lệnh dưới dạng fc.exe. Xin lưu ý rằng nhiều tiện ích DOS không xử lý mã hóa UTF-8.

Bạn cũng có thể sinh ra một quy trình CMD và chạy fc trong đó.

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

Điều này hướng dẫn PowerShell bắt đầu một quy trình với chương trình 'cmd' bằng cách sử dụng các tham số trong dấu ngoặc kép. Trong dấu ngoặc kép, là tùy chọn '/ c' cmd để chạy lệnh và chấm dứt. Lệnh thực tế để chạy bởi cmd trong quá trình là fc filea.txt fileb.txt chuyển hướng đầu ra đến tệp diff.txt.

Bạn có thể sử dụng DOS fc.exe từ bên trong powershell.

32
phord350

diff trên * nix không phải là một phần của Shell, mà là một ứng dụng riêng biệt.

Có bất kỳ lý do nào bạn không thể chỉ sử dụng diff.exe trong PowerShell không?

Bạn có thể tải xuống một phiên bản từ gói UnxUtils ( http://unxutils.sourceforge.net/ )

7
Mikeage

so sánh đối tượng (còn gọi là bí danh khác) là thảm hại nếu bạn mong đợi nó hoạt động giống như một unix diff. Tôi đã thử diff (gc file1) (gc file2) và nếu một dòng quá dài, tôi không thể thấy diff thực tế và quan trọng hơn, tôi không thể biết số dòng khác được bật.

Khi tôi thử thêm -passthru, bây giờ tôi có thể thấy sự khác biệt, nhưng tôi mất tập tin khác biệt và tôi vẫn không nhận được số dòng.

Lời khuyên của tôi, đừng sử dụng powershell để tìm sự khác biệt trong các tập tin. Như một người khác đã lưu ý, fc hoạt động và hoạt động tốt hơn một chút so với đối tượng so sánh, và thậm chí tốt hơn là tải xuống và sử dụng các công cụ thực như trình giả lập unix mà Mikeage đã đề cập.

4
Marc Towersap

Như những người khác đã lưu ý, nếu bạn đang mong đợi một đầu ra khác biệt unix-y, sử dụng bí danh diffhell diff sẽ khiến bạn thất vọng. Đối với một điều, bạn phải nắm trong tay thực sự đọc các tệp (với gc/get-content). Mặt khác, chỉ báo khác biệt nằm ở bên phải, cách xa nội dung - đó là một cơn ác mộng dễ đọc.

Giải pháp cho bất cứ ai tìm kiếm một đầu ra lành mạnh là

  1. có được một sự khác biệt thực sự (ví dụ từ GnuWin32)
  2. chỉnh sửa% USERPROFILE%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
  3. thêm dòng

    remove-item alias:diff -force
    

Đối số-Force là bắt buộc vì Powershell khá quý về bí danh sẵn có cụ thể này. Nếu bất cứ ai quan tâm, đã cài đặt GnuWin32, tôi cũng bao gồm những điều sau đây trong hồ sơ quyền hạn của mình:

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

Chủ yếu là vì Powershell không hiểu các đối số được chạy cùng nhau và gõ, ví dụ "rm -Force -Recurse" nỗ lực hơn nhiều so với "rm -rf".

Powershell có một số tính năng Nice, nhưng có một số điều không nên cố gắng làm cho tôi.

3
daf

WinMerge là một công cụ tìm kiếm dựa trên GUI tốt khác.

2
Andy White

fc.exe Tốt hơn cho việc so sánh văn bản vì nó được thiết kế để hoạt động như * nix diff, tức là so sánh các dòng một cách tuần tự, cho thấy sự khác biệt thực tế và cố gắng đồng bộ hóa lại (nếu các phần khác nhau có độ dài khác nhau). Nó cũng có một số tùy chọn điều khiển hữu ích (văn bản/nhị phân, độ nhạy trường hợp, số dòng, độ dài đồng bộ hóa, kích thước bộ đệm không khớp) và cung cấp trạng thái thoát (-1 cú pháp xấu, 0 tệp giống nhau, 1 tệp khác nhau, thiếu 2 tệp). Là một tiện ích DOS (rất) cũ, nó có một vài hạn chế. Đáng chú ý nhất là nó không tự động hoạt động với Unicode, xử lý 0 MSB của ASCII ký tự làm dấu kết thúc dòng để tệp trở thành một chuỗi gồm 1 dòng ký tự (@kennycoc: sử dụng tùy chọn/U để chỉ định các tệp BOTH là Unicode, WinXP trở đi) và nó cũng có kích thước bộ đệm dòng cứng là 128 ký tự (128 byte ASCII, 256 byte Unicode) để các dòng dài được tách ra và so sánh riêng.

đối tượng so sánh được thiết kế để xác định xem 2 đối tượng có giống nhau không? nếu các đối tượng là các bộ sưu tập thì chúng được coi là SETS (xem đối tượng trợ giúp so sánh), tức là các bộ sưu tập UNORDERED không có bản sao. 2 bộ bằng nhau nếu chúng có cùng các mục thành viên không phân biệt thứ tự hoặc trùng lặp. Điều này hạn chế nghiêm trọng tính hữu ích của nó để so sánh các tệp văn bản cho sự khác biệt. Đầu tiên, hành vi mặc định thu thập các khác biệt cho đến khi toàn bộ đối tượng (tệp = mảng chuỗi) đã được kiểm tra, do đó làm mất thông tin liên quan đến vị trí của các khác biệt và che khuất sự khác biệt nào được ghép nối (và không có khái niệm về số dòng cho SET của chuỗi). Sử dụng -synchwindow 0 sẽ khiến các khác biệt được phát ra khi chúng xảy ra nhưng ngăn không cho nó cố gắng đồng bộ hóa lại, vì vậy nếu một tệp có thêm một dòng thì việc so sánh dòng tiếp theo có thể thất bại ngay cả khi các tệp giống hệt nhau (cho đến khi có bù trừ dòng bổ sung trong tập tin khác do đó sắp xếp lại các dòng phù hợp). Tuy nhiên, powershell cực kỳ linh hoạt và việc so sánh tệp hữu ích có thể được thực hiện bằng cách sử dụng chức năng này, mặc dù phải trả giá bằng sự phức tạp đáng kể và với một số hạn chế về nội dung của các tệp. Nếu bạn cần so sánh các tệp văn bản với các dòng dài (> 127 ký tự) và trong đó các dòng hầu như khớp với 1: 1 (một số thay đổi trong các dòng giữa các tệp nhưng không có sự trùng lặp trong một tệp như danh sách văn bản của các bản ghi cơ sở dữ liệu có trường khóa) sau đó bằng cách thêm thông tin vào từng dòng cho biết đó là tệp nào, vị trí của nó trong tệp đó và sau đó bỏ qua thông tin được thêm vào trong khi so sánh (nhưng bao gồm nó trong đầu ra), bạn có thể nhận được một * nix diff like output như sau (viết tắt bí danh được sử dụng ):

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

trong đó xx là độ dài của dòng dài nhất + 9

Giải trình

  • (gc file | % -begin { $ln=0 } -process { '{0,6}<<:{1}' -f ++$ln,$_ }) Lấy nội dung của tệp và thêm số dòng và chỉ báo tệp (<< hoặc >>) cho mỗi dòng (sử dụng toán tử chuỗi định dạng) trước khi chuyển nó sang diff.
  • -property { $_.substring(9) } yêu cầu diff so sánh từng cặp đối tượng (chuỗi) bỏ qua 9 ký tự đầu tiên (là số dòng và chỉ báo tệp). Điều này sử dụng khả năng chỉ định một thuộc tính được tính toán (giá trị của khối tập lệnh) thay vì tên của một thuộc tính.
  • -passthru Gây ra khác biệt cho đầu ra các đối tượng đầu vào khác nhau (bao gồm số dòng và chỉ báo tệp) thay vì các đối tượng được so sánh khác nhau (không có).
  • sort-object Sau đó đặt tất cả các dòng trở lại thành chuỗi.
    [.___.] Chuỗi ngoài dừng cắt ngắn đầu ra mặc định để vừa với chiều rộng màn hình (như được lưu ý bởi Marc Towersap) bằng cách chỉ định chiều rộng đủ lớn để tránh cắt ngắn. Thông thường, đầu ra này sẽ được đưa vào một tệp sau đó được xem bằng trình chỉnh sửa cuộn (ví dụ: notepad).

Ghi chú

Định dạng số dòng {0,6} cung cấp một số dòng ký tự được điền vào khoảng trống, hợp lý (để sắp xếp). Nếu các tệp có nhiều hơn 999.999 dòng thì chỉ cần thay đổi định dạng để rộng hơn. Điều này cũng yêu cầu thay đổi tham số $_.substring (Nhiều hơn 3 chiều rộng số dòng) và giá trị xx ngoài chuỗi (độ dài dòng tối đa + $_.substring).

1
codemaster bob

Ngoài ra còn có Windiff cung cấp giao diện tìm khác biệt GUI (rất phù hợp để sử dụng với các chương trình CVS/SVN dựa trên GUI)

1
saschabeaumont