Add -Raw switch to Select-String for convenience (#9901)

This commit is contained in:
Jos Koelewijn
2019-07-19 13:21:39 -07:00
committed by Andrew
parent 8de061f430
commit 48c7e112db
2 changed files with 75 additions and 17 deletions
@@ -289,10 +289,18 @@ namespace Microsoft.PowerShell.Commands
/// <summary>
/// A cmdlet to search through strings and files for particular patterns.
/// </summary>
[Cmdlet(VerbsCommon.Select, "String", DefaultParameterSetName = "File", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=113388")]
[OutputType(typeof(MatchInfo), typeof(bool))]
[Cmdlet(VerbsCommon.Select, "String", DefaultParameterSetName = ParameterSetFile, HelpUri = "https://go.microsoft.com/fwlink/?LinkID=113388")]
[OutputType(typeof(bool), typeof(MatchInfo), ParameterSetName = new[] { ParameterSetFile, ParameterSetObject, ParameterSetLiteralFile })]
[OutputType(typeof(string), ParameterSetName = new[] { ParameterSetFileRaw, ParameterSetObjectRaw, ParameterSetLiteralFileRaw })]
public sealed class SelectStringCommand : PSCmdlet
{
private const string ParameterSetFile = "File";
private const string ParameterSetFileRaw = "FileRaw";
private const string ParameterSetObject = "Object";
private const string ParameterSetObjectRaw = "ObjectRaw";
private const string ParameterSetLiteralFile = "LiteralFile";
private const string ParameterSetLiteralFileRaw = "LiteralFileRaw";
/// <summary>
/// A generic circular buffer.
/// </summary>
@@ -965,7 +973,8 @@ namespace Microsoft.PowerShell.Commands
/// <summary>
/// Gets or sets the current pipeline object.
/// </summary>
[Parameter(ValueFromPipeline = true, Mandatory = true, ParameterSetName = "Object")]
[Parameter(ValueFromPipeline = true, Mandatory = true, ParameterSetName = ParameterSetObject)]
[Parameter(ValueFromPipeline = true, Mandatory = true, ParameterSetName = ParameterSetObjectRaw)]
[AllowNull]
[AllowEmptyString]
public PSObject InputObject
@@ -988,7 +997,8 @@ namespace Microsoft.PowerShell.Commands
/// Gets or sets files to read from.
/// Globbing is done on these.
/// </summary>
[Parameter(Position = 1, Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "File")]
[Parameter(Position = 1, Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = ParameterSetFile)]
[Parameter(Position = 1, Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = ParameterSetFileRaw)]
[FileinfoToString]
public string[] Path { get; set; }
@@ -996,7 +1006,8 @@ namespace Microsoft.PowerShell.Commands
/// Gets or sets literal files to read from.
/// Globbing is not done on these.
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "LiteralFile")]
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = ParameterSetLiteralFile)]
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = ParameterSetLiteralFileRaw)]
[FileinfoToString]
[Alias("PSPath", "LP")]
public string[] LiteralPath
@@ -1011,6 +1022,15 @@ namespace Microsoft.PowerShell.Commands
private bool _isLiteralPath;
/// <summary>
/// Gets or sets a value indicating if only string values containing matched lines should be returned.
/// If not (default) return MatchInfo (or bool objects, when Quiet is passed).
/// </summary>
[Parameter(Mandatory = true, ParameterSetName = ParameterSetObjectRaw)]
[Parameter(Mandatory = true, ParameterSetName = ParameterSetFileRaw)]
[Parameter(Mandatory = true, ParameterSetName = ParameterSetLiteralFileRaw)]
public SwitchParameter Raw { get; set; }
/// <summary>
/// Gets or sets a value indicating if a pattern string should be matched literally.
/// If not (default) search using pattern as a Regular Expression.
@@ -1028,7 +1048,9 @@ namespace Microsoft.PowerShell.Commands
/// Gets or sets a value indicating if the cmdlet will stop processing at the first successful match and
/// return true. If both List and Quiet parameters are given, an exception is thrown.
/// </summary>
[Parameter]
[Parameter(ParameterSetName = ParameterSetObject)]
[Parameter(ParameterSetName = ParameterSetFile)]
[Parameter(ParameterSetName = ParameterSetLiteralFile)]
public SwitchParameter Quiet { get; set; }
/// <summary>
@@ -1160,7 +1182,10 @@ namespace Microsoft.PowerShell.Commands
private int _postContext = 0;
private IContextTracker GetContextTracker() => (_preContext == 0 && _postContext == 0) ? _noContextTracker : new ContextTracker(_preContext, _postContext);
// When we are in Raw mode or pre- and postcontext are zero, use the _noContextTracker, since we will not be needing trackedLines.
private IContextTracker GetContextTracker() => (Raw || (_preContext == 0 && _postContext == 0))
? _noContextTracker
: new ContextTracker(_preContext, _postContext);
// This context tracker is only used for strings which are piped
// directly into the cmdlet. File processing doesn't need
@@ -1425,8 +1450,14 @@ namespace Microsoft.PowerShell.Commands
return false;
}
// If -quiet is specified but not -list return true on first match
if (Quiet && !List)
if (Raw)
{
foreach (MatchInfo match in contextTracker.EmitQueue)
{
WriteObject(match.Line);
}
}
else if (Quiet && !List)
{
WriteObject(true);
}
@@ -68,7 +68,7 @@ Describe "Select-String" -Tags "CI" {
}
it "Should return an array of non matching strings when the switch of NotMatch is used and the string do not match" {
$testinputone | Select-String -Pattern "goodbye" -NotMatch | Should -Be "hello", "hello"
$testinputone | Select-String -Pattern "goodbye" -NotMatch | Should -BeExactly "hello", "Hello"
}
it "Should return the same as NotMatch" {
@@ -76,7 +76,16 @@ Describe "Select-String" -Tags "CI" {
$secondMatch = $testinputone | Select-String -pattern "goodbye" -n
$equal = @(Compare-Object $firstMatch $secondMatch).Length -eq 0
$equal | Should -Be True
$equal | Should -BeTrue
}
It "Should return a string type when -Raw is used" {
$result = $testinputtwo | Select-String -Pattern "hello" -CaseSensitive -Raw
$result | Should -BeOfType "System.String"
}
It "Should return ParameterBindingException when -Raw and -Quiet are used together" {
{ $testinputone | Select-String -Pattern "hello" -Raw -Quiet -ErrorAction Stop } | Should -Throw -ExceptionType ([System.Management.Automation.ParameterBindingException])
}
}
@@ -106,13 +115,13 @@ Describe "Select-String" -Tags "CI" {
It "Should return the name of the file and the string that 'string' is found if there is only one lines that has a match" {
$expected = $testInputFile + ":1:This is a text string, and another string"
Select-String $testInputFile -Pattern "string" | Should -Be $expected
Select-String $testInputFile -Pattern "string" | Should -BeExactly $expected
}
It "Should return all strings where 'second' is found in testfile1 if there is only one lines that has a match" {
$expected = $testInputFile + ":2:This is the second line"
Select-String $testInputFile -Pattern "second"| Should -Be $expected
Select-String $testInputFile -Pattern "second"| Should -BeExactly $expected
}
It "Should return all strings where 'in' is found in testfile1 pattern switch is not required" {
@@ -121,10 +130,10 @@ Describe "Select-String" -Tags "CI" {
$expected3 = "This is the third line"
$expected4 = "This is the fourth line"
(Select-String in $testInputFile)[0].Line | Should -Be $expected1
(Select-String in $testInputFile)[1].Line | Should -Be $expected2
(Select-String in $testInputFile)[2].Line | Should -Be $expected3
(Select-String in $testInputFile)[3].Line | Should -Be $expected4
(Select-String in $testInputFile)[0].Line | Should -BeExactly $expected1
(Select-String in $testInputFile)[1].Line | Should -BeExactly $expected2
(Select-String in $testInputFile)[2].Line | Should -BeExactly $expected3
(Select-String in $testInputFile)[3].Line | Should -BeExactly $expected4
(Select-String in $testInputFile)[4].Line | Should -BeNullOrEmpty
}
@@ -175,6 +184,24 @@ Describe "Select-String" -Tags "CI" {
Select-String 'matc*' $testInputFile -ca | Should -Match $expected
}
It "Should return all strings where 'in' is found in testfile1, when -Raw is used." {
$expected1 = "This is a text string, and another string"
$expected2 = "This is the second line"
$expected3 = "This is the third line"
$expected4 = "This is the fourth line"
(Select-String in $testInputFile -Raw)[0] | Should -BeExactly $expected1
(Select-String in $testInputFile -Raw)[1] | Should -BeExactly $expected2
(Select-String in $testInputFile -Raw)[2] | Should -BeExactly $expected3
(Select-String in $testInputFile -Raw)[3] | Should -BeExactly $expected4
(Select-String in $testInputFile -Raw)[4] | Should -BeNullOrEmpty
}
It "Should ignore -Context parameter when -Raw is used." {
$expected = "This is the second line"
Select-String second $testInputFile -Raw -Context 2,2 | Should -BeExactly $expected
}
}
Push-Location $currentDirectory
}