• Aucun résultat trouvé

Comparisons and case sensitivity

Dans le document Bruce PayetteSECOND EDITION (Page 158-162)

Operators and expressions

4.3 C OMPARISON OPERATORS

4.3.2 Comparisons and case sensitivity

Next let’s look at the “i” and “c” versions of the comparison operators—the case-sensitive and case-incase-sensitive versions. Obviously, case sensitivity only applies to strings. All the comparison operators have both versions. For example, the -eq opera-tor has the following variants:

PS (1) > "abc" -eq "ABC"

True

PS (2) > "abc" -ieq "ABC"

True

PS (3) > "abc" -ceq "ABC"

False

The default case -eq is case insensitive, as is the explicitly case-insensitive operator -ieq, so in the example, “abc” and “ABC” compare as equal. The -ceq operator is case sensitive, so with this operator, “abc” and “ABC” compare as not equal.

The final item to discuss with scalar comparisons is how things that aren’t strings and numbers are compared. In this case, the .NET comparison mechanisms are used. If the object implements the .NET IComparable interface, then that will be used. If not, and if the object on the left side has an .Equals() method that can take an object of the type of the right operand, this is used. If there’s no direct mechanism for comparing the two, an attempt will be made to convert the right operand into an instance of the type of the left operand, and then PowerShell will

try to compare the resulting objects. This lets you compare things such as [Date-Time] objects, as shown here:

PS (4) > [DateTime] "1/1/2010" -gt [DateTime] "1/1/2009"

True

PS (5) > [DateTime] "1/1/2010" -gt [DateTime] "2/1/2010"

False PS (6) >

Not all objects are directly comparable. For example, there’s no direct way to compare a System.DateTime object to a System.Diagnostics.Process object:

PS (6) > [DateTime] "1/1/2010" -gt (Get-Process)[0]

The '-gt' operator failed: Cannot convert

"System.Diagnostics.Process (ALCXMNTR)" to "System.DateTime"..

At line:1 char:26

+ [] "1/1/2010" -gt <<<< (Get-Process)[0]

PS (7) >

In this example, because there’s no direct way to compare a DateTime object to a Process object, the next step is to try to convert the Process object into an instance of DateTime. This also failed, and as this is the last step in the comparison algorithm, an error message is produced explaining what happened. This is where a human has to intervene. The obvious field on a Process object to compare is the StartTime of the process. Use the property notation to do this:

PS (7) > [DateTime] "1/1/2010" -gt (Get-Process)[0].StartTime False

PS (8) > [DateTime] "1/1/2011" -gt (Get-Process)[0].StartTime True

In this expression, you’re looking to see whether the first element in the list of Pro-cess objects had a start time greater than the beginning of this year (no) and whether it had a start time from before the beginning of next year (obviously true). You can use this approach to find all the processes on a computer that started today:

Get-Process | where {$_.starttime -ge [DateTime]::today}

The Get-Process cmdlet returns a list of all the processes on this computer, and the where cmdlet selects those processes where the StartTime property of the process is greater than or equal to today.

NOTE The where used in the previous example is an alias for the Where-Object cmdlet, which is described in chapter 6.

This completes our discussion of the behavior of the comparison operators with sca-lar data. We paid a lot of attention to the role types play in comparisons, but so far we’ve avoided discussing collection types—lists, arrays, and so on. We’ll get to that in the next section.

COMPARISONOPERATORS 129 4.3.3 Using comparison operators with collections

In this section, we’ll focus on the behavior of the comparison operators when they’re used with collections of objects.

Basic comparison operations involving collections

Here’s the basic behavior. If the left operand is an array or collection, the comparison operation will return the elements of that collection that match the right operand.

Let’s illustrate the rule with an example:

PS (1) > 1,2,3,1,2,3,4 -eq 2 2

2

This expression searches the list of numbers on the left side and returns those that match—the two “2”s. And this works with strings as well:

PS (2) > "one","two","three","two","one" -eq "two"

two two

When processing the array, the scalar comparison rules are used to compare each ele-ment. In the next example, the left operand is an array containing a mix of numbers and strings, and the right operand is the string “2”:

PS (3) > 1,"2",3,2,"1" -eq "2"

2 2

Again, it returns the two “2”s. Let’s look at some more examples where you have lead-ing zeros in the operands. In the first example

PS (4) > 1,"02",3,02,"1" -eq "2"

2

you only return the number 2 because 2 and “02” compare equally in a numeric con-text, but “2” and “02” are different in a string context. The same thing happens in the next example:

PS (5) > 1,"02",3,02,"1" -eq 2 2

When the elements are compared as numbers, they match. When compared as strings, they don’t match because of the leading zero. Now one final example:

PS (6) > 1,"02",3,02,"1" -eq "02"

02 2

They both match. In a numeric context, the leading zeros don’t matter; and in the string context, the strings match.

The containment operators

All of the comparison operators we’ve discussed so far return the matching elements from the collection. Although this is extremely useful, there are times when you just want to find out whether or not an element is there. This is what the -contains and -notcontains operators, shown in figure 4.5, are for.

These operators return $True if the set contains the element you’re looking for instead of returning the matching elements. They’re listed in table 4.4 with examples.

Let’s redo the example at the end of the previous section, but this time you’ll use -contains instead of -eq:

PS (1) > 1,"02",3,02,"1" -contains "02"

True

PS (2) > 1,"02",3,02,"1" -notcontains "02"

False

Now, instead of returning 02 and 2, you just return a single Boolean value. Because all values in PowerShell can be converted into a Boolean value, this doesn’t seem as if it would particularly matter, and usually it doesn’t. The one case where it does matter is if the matching set of elements is something that’s false. This even includes Bool-eans. The concept is easier to understand with an example:

PS (3) > $false,$true -eq $false False

PS (4) > $false,$true -contains $false True

The collection on the left side contains the value specified on the right side.

1,2,3 –contains 2 $true

-notcontains -cnotcontains -inotcontains

The collection on the left side doesn’t contain the value specified on the right side.

1,2,3 –notcontains 2 $false -contains -notcontains -icontains -inotcontains

Containment operators (case-insensitive)

-ccontains -cnotcontains

Containment operators (case-sensitive) Figure 4.5 The Power-Shell containment operators in case-insensitive and case-sensitive versions

PATTERNMATCHINGANDTEXTMANIPULATION 131 In the first command, -eq searches the list for $false, finds it, and then returns the matching value. But because the matching value was literally $false, a successful match looks as if it failed. When you use the -contains operator in the expression, you get the result you’d expect, which is $true. The other way to work around this issue is to use the @( .. ) construction and the Count property:

PS (5) > @($false,$true -eq $false).count 1

The @( ... ) sequence forces the result to be an array and then takes the count of the results. If there are no matches the count will be zero, which is equivalent to

$false. If there are matches the count will be nonzero, equivalent to $true. There can also be some performance advantages to -contains, because it stops looking on the first match instead of checking every element in the list.

NOTE The @( .. ) construction is described in detail in chapter 5.

In this section, we covered all the basic comparison operators. We addressed the issue of case sensitivity in comparisons, and we covered the polymorphic behavior of these operations, first for scalar data types, then for collections. Now let’s move on to look at PowerShell’s operators for working with text. One of the hallmark features of dynamic languages is great support for text manipulation and pattern matching. In the next sec-tion, we’ll cover how PowerShell incorporates these features into the language.

Dans le document Bruce PayetteSECOND EDITION (Page 158-162)