Windows Powershell에서 두 개의 텍스트 파일을 어떻게 다른가요?


96

두 개의 텍스트 파일이 있는데 Windows Powershell을 사용하여 차이점을 찾고 싶습니다. 유닉스 diff 도구와 비슷한 것이 있습니까? 아니면 내가 고려하지 않은 다른 방법이 있습니까?

비교 객체를 시도했지만이 암호 출력을 얻습니다.

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

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

답변:


101

그것을 스스로 알아 냈습니다. Powershell은 텍스트가 아닌 .net 객체와 작동하므로 텍스트 파일의 내용을 표시하려면 get-content를 사용해야합니다. 그래서 질문에서하려고했던 것을 수행하려면 다음을 사용하십시오.

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

1
정렬되지 않은 숫자 배열과 정렬 후 동일한 숫자 배열을 비교하려고 할 때 매우 놀랐습니다. 파일이 매우 다르더라도 출력이 없습니다. 분명히, 객체는 순서를 고려하지 않습니다.
cgmb

1
@cgmb- -SyncWindow 0최근에 소개되었는지 확실하지 않지만 문제를 해결하는 데 사용할 수 있습니다 . 그러나 특별히 똑똑하지는 않습니다.
James Ruskin

32

간단한 방법은 다음과 같습니다.

diff (cat file1) (cat file2)

15
Diff와 cat은 PowerShell에서 Compare-Object 및 Get-Content의 별칭 일뿐입니다. 같은 것입니다.
Shawn Melton 2012

4
이 허용 대답과 동일 임에도 불구하고, 좀 더이 구문을 사용하여 좋아
엘리야 W. 가니

diff다른 답변에서 언급 했듯이 * nix처럼 전혀 행동하지 않습니다 . 그리고 내가 대신에 복잡한 표현을 사용했을 때 cat잘못된 결과를 얻었으므로 * nix에서 온 경우 PowerShell 에서이 작업을 수행하지 않도록 권장 사항에 다른 사람들과 합류 할 것입니다.
Nickolay

29

또는 DOS fc명령을 사용할 수 있습니다 (두 파일의 출력을 표시하므로 차이점을 스캔해야합니다).

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

fc는 Format-Custom cmdlet의 별칭이므로 명령을로 입력해야합니다fc.exe . 많은 DOS 유틸리티는 UTF-8 인코딩을 처리하지 않습니다.

CMD 프로세스를 생성하고 fc그 안에서 실행할 수도 있습니다.

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

그러면 PowerShell에서 매개 변수를 따옴표로 묶어 'cmd'프로그램으로 프로세스를 시작하도록 지시합니다. 따옴표 안에 명령을 실행하고 종료하는 '/ c'cmd 옵션이 있습니다. 프로세스에서 cmd가 실행하는 실제 명령 fc filea.txt fileb.txt은 출력을 파일로 리디렉션하는 것 diff.txt입니다.

fc.exepowershell 내 에서 DOS 를 사용할 수 있습니다 .


2
DOS를 가져 오려면 +1 ^ _ ^
Jeff Bridgman

1
"fc"가 작동하지 않았으며 Format-Custom과 구별하기 위해 "fc.exe"로 지정해야한다는 것을 몰랐습니다. 정확히 내가 찾던 것. 감사.
Xonatron

어쩌면 나는 완전한 필레 스틴이지만, 이것은 나에게 훨씬 더 유용한 것처럼 보인다. 내 문제를 아주 잘 해결했습니다.
AJ.

유일한 문제는 HATES 유니 코드입니다.
iCodeSometime

7

dinix on diff는 쉘의 일부가 아니라 별도의 응용 프로그램입니다.

PowerShell에서 diff.exe를 사용할 수없는 이유가 있습니까?

UnxUtils 패키지 ( http://unxutils.sourceforge.net/ ) 에서 버전을 다운로드 할 수 있습니다.


10
이제 PowerShell이 ​​포함되어 있으므로 다운로드 및 설치할 항목이 없습니다.
Bratch

git diff이미 설치했기 때문에 방금 사용 했습니다. 내가 기대 한 결과물 fc.exeCompare-Object생산 하지도 않았다 .
Raziel

4

비교 객체 (일명 diff 별명)는 유닉스 diff와 같은 행동을 기대한다면 한심한 것입니다. diff (gc file1) (gc file2)를 시도했지만 줄이 너무 길면 실제 diff를 볼 수 없으며 더 중요한 것은 diff가 어느 줄 번호에 있는지 알 수 없습니다.

-passthru를 추가하려고하면 이제 차이점을 볼 수 있지만 차이점이있는 파일을 잃어 버리고 여전히 줄 번호를 얻지 못합니다.

내 조언, 파일의 차이점을 찾기 위해 powershell을 사용하지 마십시오. 다른 사람이 지적했듯이 fc는 비교 객체보다 작동하고 조금 더 잘 작동하며 Mikeage가 언급 한 유닉스 에뮬레이터와 같은 실제 도구를 다운로드하여 사용하는 것이 더 좋습니다.


또한 -SyncWindow기본적으로 maxint 와 같이 설정된 비교 (즉, 순서 무시)를 수행하는 것으로 보입니다 . 0으로 설정해도 작동하지 않습니다 diff... 파이프 (... | select-object ...)를 입력으로 전달하면 넌센스가 인쇄되어 포기했습니다.
Nickolay

3

다른 사람들이 지적했듯이, UNIX diff 출력을 기대하고 있다면 powershell diff 별칭을 사용하면 어려움을 겪을 수 있습니다. 우선, 실제로 파일을 읽는 데 손을 잡고 있어야합니다 (gc / get-content). 다른 점으로는 차이 표시가 내용과는 거리가 먼 오른쪽에 있습니다. 가독성 악몽입니다.

제정신 출력을 찾는 모든 사람을위한 솔루션은

  1. 실제 diff를 얻습니다 (예 : GnuWin32에서)
  2. % USERPROFILE % \ Documents \ WindowsPowerShell \ Microsoft.PowerShell_profile.ps1 편집
  3. 라인을 추가

    remove-item alias:diff -force

Powershell은이 내장 된 별명에 대해 매우 귀중하므로 -force 인수가 필요합니다. GnuWin32를 설치하고 싶은 사람이라면 powershell 프로필에 다음 내용도 포함시킵니다.

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

Powershell은 함께 실행되고 입력되는 인수를 이해하지 못하므로 "rm -Force -Recurse"는 "rm -rf"보다 훨씬 많은 노력이 필요합니다.

Powershell에는 멋진 기능이 있지만 나를 위해 시도해서는 안되는 몇 가지 사항이 있습니다.


2

WinMerge 는 또 다른 유용한 GUI 기반 diff 도구입니다.


1
이것이 내가 과거에 한 일입니다. 수동 프로세스이기 때문에 작은 스크립트로 바꾸고 싶었습니다.
Bratch

1

GUI diff 인터페이스를 제공하는 Windiff 도 있습니다 (GUI 기반 CVS / SVN 프로그램과 함께 사용하기에 적합)


1

fc.exe* nix diff와 같이 작동하도록 디자인 되었기 때문에 텍스트를 비교하는 것이 좋습니다. 즉, 실제 차이를 표시하고 다시 동기화하려고합니다 (서로 다른 섹션의 길이가 다른 경우). 또한 유용한 제어 옵션 (텍스트 / 이진, 대소 문자 구분, 줄 번호, 재 동기화 길이, 불일치 버퍼 크기)이 있으며 종료 상태 (-1 잘못된 구문, 0 파일 동일, 1 파일 차이, 2 파일 누락)를 제공합니다. (매우) 오래된 DOS 유틸리티이기 때문에 몇 가지 제한이 있습니다. 특히, ASCII 문자의 0 MSB를 줄 종결 자로 처리하여 유니 코드와 자동으로 작동하지 않으므로 파일이 1 문자 행의 시퀀스가됩니다 (@kennycoc : / U 옵션을 사용하여 BOTH 파일을 유니 코드, WinXP 이상으로 지정) ) 또한 하드 라인 버퍼 크기는 128 자 (128 바이트 ASCII,

compare-object는 2 개의 객체가 멤버 단위로 동일한지를 결정하도록 설계되었습니다. 개체가 컬렉션 인 경우 개체는 SETS (개체 비교 도움말 참조), 즉 복제되지 않은 UNORDERED 컬렉션으로 처리됩니다. 2 세트는 주문 또는 복제와 상관없이 동일한 멤버 항목을 갖는 경우 동일합니다. 이것은 텍스트 파일의 차이점을 비교하는 데 그 유용성을 크게 제한합니다. 첫째, 기본 동작은 전체 객체 (파일 = 문자열 배열)를 확인할 때까지 차이를 수집하여 차이의 위치에 관한 정보를 잃고 차이가 쌍을 이루지 못하게합니다 (그리고 SET에 대한 줄 번호 개념이 없습니다) 문자열). -synchwindow 0을 사용하면 차이가 발생할 때 차이가 발생하지만 재 동기화 시도가 중지되므로 한 파일에 추가 라인이 있으면 파일이 다른 경우에도 후속 라인 비교가 실패 할 수 있습니다 (보상이있을 때까지) 다른 파일에 여분의 줄을 추가하여 일치하는 줄을 다시 정렬하십시오). 그러나 powershell은 매우 다양하며 파일 기능에 약간의 제한이 있지만이 기능을 활용하면 유용한 파일 비교를 수행 할 수 있습니다. 텍스트 파일을 긴 (> 127 자) 행과 비교하고 행이 대부분 1과 일치하는 경우 :

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는 가장 긴 줄의 길이 + 9

설명

  • (gc file | % -begin { $ln=0 } -process { '{0,6}<<:{1}' -f ++$ln,$_ }) 파일의 내용을 가져 와서 diff에 전달하기 전에 행 번호와 파일 표시기 (<< 또는 >>)를 각 행 앞에 추가합니다 (형식 문자열 연산자 사용).
  • -property { $_.substring(9) }diff가 처음 9자를 무시하는 각 객체 (문자열) 쌍을 비교하도록 지시합니다 (행 번호 및 파일 표시기). 이는 속성 이름 대신 계산 된 속성 (스크립트 블록의 값)을 지정하는 기능을 활용합니다.
  • -passthru diff가 다른 비교 대상 개체 (행하지 않는) 대신 다른 입력 개체 (행 번호 및 파일 표시기 포함)를 출력합니다.
  • sort-object그런 다음 모든 줄을 순서대로 되돌립니다.
    out-string은 잘림을 피하기에 충분히 큰 너비를 지정하여 화면 너비에 맞게 출력의 기본 잘림을 중지합니다 (Marc Towersap에서 명시한대로). 일반적으로이 출력은 파일에 저장되고 스크롤 편집기 (예 : 메모장)를 사용하여 볼 수 있습니다.

노트

줄 번호 형식 {0,6}은 오른쪽 정렬 된 공백으로 채워진 6 자 줄 번호 (정렬 용)를 제공합니다. 파일의 행이 999,999 개를 초과하면 형식을 더 크게 변경하십시오. 또한 $_.substring매개 변수 (행 번호 너비보다 3 이상)와 문자열 외부 xx 값 (최대 행 길이 + $_.substring매개 변수)을 변경해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.