Answers:
我自己想通了。由于Powershell使用的是.net对象而不是文本,因此您需要使用get-content公开文本文件的内容。因此,要执行我在问题中试图做的事情,请使用:
compare-object (get-content one.txt) (get-content two.txt)
-SyncWindow 0
我相信,您可以使用它来解决此问题,尽管我不确定它是否只是最近才引入的。不过,这并不是特别聪明。
一种更简单的方法是编写:
diff (cat file1) (cat file2)
diff
,正如这里的其他答案所述。当我使用更复杂的表达式代替cat
错误输出时,因此如果您来自* nix,我将与其他建议一起加入以避免在PowerShell中执行此操作。
或者,您可以fc
像这样使用DOS 命令(这显示了两个文件的输出,因此您必须扫描差异):
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.exe
在powershell中使用DOS 。
* nix上的差异不是外壳程序的一部分,而是单独的应用程序。
有什么原因不能只在PowerShell下使用diff.exe?
您可以从UnxUtils包(http://unxutils.sourceforge.net/)下载版本。
git diff
,因为我已经安装了它。既不fc.exe
也不Compare-Object
产生我期望的输出。
如果您希望比较对象(例如diff别名)表现得像Unix diff一样,那是可悲的。我尝试了diff(gc file1)(gc file2),如果一行太长,我看不到实际的diff,更重要的是,我无法确定diff所在的行号。
当我尝试添加-passthru时,现在可以看到区别,但是我丢失了区别所在的文件,但仍然没有获得行号。
我的建议是,不要使用powershell查找文件中的差异。正如其他人指出的那样,fc可以工作,并且比比较对象要好一些,甚至更好的是下载和使用Mikeage提到的诸如unix模拟器的真实工具。
-SyncWindow
默认情况下,maxint 似乎也进行了集合比较(即忽略顺序)。将其设置为0并不会使其工作diff
……当我通过管道(... | select-object ...)
作为输入时,它只是打印废话,所以我放弃了。
正如其他人指出的那样,如果您期望使用unix-y diff输出,那么使用powershell diff别名会让您失望。一方面,您必须握住它来实际读取文件(使用gc / get-content)。另一方面,差异指示器位于右侧,距离内容很远-这是可读性的噩梦。
对于任何寻求合理输出的解决方案是
添加线
remove-item alias:diff -force
-force参数是必需的,因为Powershell对于此特定的内置别名非常宝贵。如果有人感兴趣,安装了GnuWin32,我还将在powershell配置文件中添加以下内容:
remove-item alias:rm
remove-item alias:mv
remove-item alias:cp
主要是因为Powershell无法理解同时运行并键入的参数,例如,“ rm -Force -Recurse”比“ rm -rf”需要更多的精力。
Powershell具有一些不错的功能,但是有些事情它不应该为我做。
fc.exe
比较适合于文本比较,因为它的设计类似于* nix diff,即按顺序比较行,显示实际差异并尝试重新同步(如果不同部分的长度不同)。它还具有一些有用的控制选项(文本/二进制,区分大小写,行号,重新同步长度,不匹配的缓冲区大小),并提供退出状态(-1错误的语法,0个相同的文件,1个不同的文件,2个丢失的文件)。作为(非常)旧的DOS实用程序,它确实有一些限制。最值得注意的是,它不能自动与Unicode一起使用,将0个ASCII字符的MSB作为行终止符,因此文件变成1个字符行的序列(@kennycoc:使用/ U选项指定两个文件均为Unicode,从WinXP开始),并且硬线缓冲区大小为128个字符(128个字节的ASCII,
compare-object用于确定2个对象在成员方面是否相同。如果对象是集合,则将它们视为SETS(请参阅帮助比较对象),即无重复的UNORDERED集合。如果成员项相同,则无论顺序或重复项如何,两组都相等。这严重限制了它在比较文本文件是否有差异方面的有用性。首先,默认行为会收集差异,直到检查了整个对象(文件=字符串数组),从而丢失了有关差异位置的信息,并模糊了配对的差异(并且SET中没有行号的概念)的字符串)。使用-synchwindow 0会导致差异出现时发出,但是会阻止差异尝试重新同步,因此,如果一个文件有多余的行,那么即使这些文件是相同的,后续的行比较也可能失败(直到有补偿)其他文件中的多余行,从而重新对齐匹配的行)。但是,powershell具有极强的通用性,并且可以通过利用此功能来完成有用的文件比较,尽管这样做的代价是相当复杂,并且对文件内容有一些限制。如果您需要比较文本行较长(> 127个字符)并且文本行大部分匹配的文本文件,请执行以下操作:
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
然后将所有行放回序列中。行号格式{0,6}给出一个右对齐的空格填充6个字符的行号(用于排序)。如果文件的行数超过999,999,则只需将格式更改为更宽即可。这还需要更改$_.substring
参数(比行号宽度多3)和字符串xx值(最大行长+ $_.substring
参数)。