我正在编写一个PowerShell脚本,将以下内容转换为一个脚本,该脚本接受2个文件作为命令行参数,然后将两个文件的差异输出到文本文件。
目前,我的无用代码如下:
# Compare two text files passed as command line arguments
Function compareFiles()
{
Param (
[Parameter(mandatory=$true)]
[string]$file1,
[string]$file2
)
$file1 = resolve-path \.$file1
$file2 = resolve-path \.$file2
if ($file1 -eq $null) {
Write-Host "No source file."
}
if ($file2 -eq $null) {
Write-Host "No comparison file."
}
# Compare the two file objects
# => means $file2 has that line but not $file1
# =< means $file1 has that line but not $file2
# to see lines that arw the same, add -includeequal to end of the following line
Compare-Object -ReferenceObject (Get-Content $file1) -DifferenceObject (Get-Content $file2) | Out-File "$file1_$file2_Compare.txt" -Force
}
在PowerShell控制台中,定义Compare-Object -ReferenceObject (Get-Content $obj1) -DifferenceObject (Get-Content $obj2
和$obj1="test1.txt"
后,行$obj2="test2.txt"
正常工作。
当我从PowerShell控制台运行.\Compare-Files.ps1 -file1 test1.txt -file2 test2.txt
时,我得到以下内容:
compareFiles : Cannot bind argument to parameter 'file1' because it is an empty string.
At C:\Users\debug255\Documents\Fiverr\PowerShell\Orders\armytra1n3d\FO4ADB39A404\Compare-Files.ps1:27 char:21
+ compareFiles -file1 $file1 -file2 $file2 | Out-File "$file1_$file2_Co ...
+ ~~~~~~
+ CategoryInfo : InvalidData: (:) [compareFiles], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,compareFiles
通过从早期测试中删除剩余的$obj1
和$obj2
变量来解决此错误
来自Hey Scripting Guy的这个脚本可以正常运行
$fileA = "test1.txt"
$fileB = "test2.txt"
if(Compare-Object -ReferenceObject $(Get-Content $fileA) -DifferenceObject $(Get-Content $fileB))
{
"files are different"
}
Else
{
"Files are the same"
}
test1.txt
包含以下内容:
test1
1
2
3
4
5
6
7
asaskjdahs
sl kasldk
test2.txt包含:
test2
1
23
3
4
5
6
799
asaskjdahs
sl kasldkJ
我在Windows 10上使用PowerShell 5.1.14393.1066。
感谢您的帮助!
修改
我完全改变了脚本以便没有比较功能,我使用了我在GitHub上找到的一个例子来打开和比较MS Word文档,这有很大帮助。
# Compare two text files passed as command line arguments
Param (
[Parameter(mandatory=$true)]
$file1,
$file2
)
$ErrorActionPreference = 'Stop'
# Remove read-only attributes from baseFile
$baseFile = Get-ChildItem $file1
if ($baseFile.IsReadOnly) {
$baseFile.IsReadOnly = $false
}
try {
Compare-Object -ReferenceObject (Get-Content $file1) -DifferenceObject (Get-Content $file2) `
| Out-File $file1"_"$file2"_Comparison.txt" -Force
}
catch {
Write-Host "There was an error"
}
但是,只要我将函数中的代码包装为compareFiles() { ... }
,当我运行相同的行而没有将其包含在函数.\Compare-Files.ps1 -file1 test1.txt -file2 test2.txt
中时,就没有任何输出。当我在函数compareFiles
下面的脚本中添加一个函数调用时,它会提示我$file1
,失败并且没有像我之前那样提示我$file2
,只是这个我的catch
抓住了它。
然后,我将Param ()
全局放在函数compareFiles
之上,并且它有效!
现在,我需要专注于清理输出一点点。输出如下:
InputObject SideIndicator
----------- -------------
test2 =>
1 =>
23 =>
3 =>
4 =>
5 =>
6 =>
799 =>
asaskjdahs =>
sl kasldkJ =>
test1 <=
1 <=
2 <=
3 <=
4 <=
5 <=
6 <=
7 <=
asaskjdahs <=
sl kasldk <=
如果您有任何建议使输出看起来像:
test2.txt:
InputObject SideIndicator
----------- -------------
test2 =>
1 =>
23 =>
3 =>
4 =>
5 =>
6 =>
799 =>
asaskjdahs =>
sl kasldkJ =>
test1.txt
test1 <=
1 <=
2 <=
3 <=
4 <=
5 <=
6 <=
7 <=
asaskjdahs <=
sl kasldk <=
此外,我注意到test1.txt
在第1,2,3,4等行上有不同的内容,但它们实际上是相同的(1
中的test1.txt
是例如,与test2.txt
相同的行。
有任何建议可以清理一下吗?
谢谢大家的帮助!
答案 0 :(得分:1)
注意:问题不断变化,代码会出现各种不相关的问题,因此很难给出有意义的答案,但这里有几点建议:
Param (
[Parameter(mandatory=$true)]
$file1,
$file2
)
仅将 $file1
定义为必填项,而不是$file2
- 每个参数都需要自己的[Parameter(...)]
属性。
\.$file1
和\.$file2
没有按照您的预期工作;也许您的意思是.\$file1
和.\$file2
来引用当前目录中的文件,但您不需要任何前缀,因为Resolve-Path
默认为无论如何目前的目录。
测试$file1 -eq $null
和$file2 -eq $null
永远不会成功,因为$file1
和$file2
由于已被宣布{{1}参数,从不 [string]
。
$null
类型变量默认为空字符串而不是[string]
,甚至显式分配 $null
结果为空字符串(将其与C#进行比较,其中$null
个变量默认为string
,并且可以分配null
。在字符串null
中扩展(插值)变量$file1
和$file2
不会起作用,因为"$file1_$file2_Compare.txt"
是合法字符变量名称,您必须将变量名称 end 告诉PowerShell,方法是将它们括在_
中:{...}