Long String Running

Doctor Scripto

Summary: Ed Wilson, Microsoft Scripting Guy, talks about using a compound string command.

Microsoft Scripting Guy, Ed Wilson, is here. The other day, the Scripting Wife and I headed to Nashville for a couple of speaking engagements. We decided to head through Alabama instead of going through Atlanta for a couple of reasons. We have never driven the length of Alabama, so we were looking for a bit of different scenery. Secondly, because we always spend a couple of hours trying to drive through Atlanta and all of the associated communities in the greater Atlanta metropolitan area (hmmmm….Gamma)?

Anyway, it was a lovely day to drive. Here is a picture I took when we got out to walk around a bit. It is really pretty, and some of the trees are actually starting to change colors. The palm trees we have in Florida don’t really change colors (that I recall), so it was a nice change of pace.

Photo of landscape

The Nashville PowerShell User Group combined with the SQL User Group, and the event was sold out. Nearly 90 people filled the meeting room at the Microsoft office. One of the questions I received was about a line of code that works with strings. In fact, there were several questions in the room, and even more comments about it on Twitter.

Compounding object notation

The line of code in question is shown in the following script:

$datain = import-csv C:\DataIn\DataDump.csv

Foreach ($d in $datain)

    {

      If($d.name -match  ',')

        {

          $name = (Get-Culture).textinfo.ToTitleCase($d.name).Split(',').trim()

          [PSCustomObject]@{

            Lname = $name[0]

            Fname = $name[1] }}

        ELSE {

         $name = $d.Name.Split().trim()

          [PSCustomObject]@{

            Fname = $name[0]

            Lname = $name[1] } }

      } 

Basically, the script reads a CSV file that contains user names, and it title cases the name, splits it into pieces at the comma, and then trims off the extra spaces from the beginning and the end of the name. Here is the exact line of code:

$name = (Get-Culture).textinfo.ToTitleCase($d.name).Split(',').trim()

What makes this line of code a bit complicated, is that it actually contains three objects. It also has an object and three methods in it. Here are the objects:

First of all, Get-Culture returns an instance of a CultureInfo object:

PS C:\> (get-culture).gettype()

IsPublic IsSerial Name                            BaseType                                        

——–   ——–   —-                                ——–                                        

False    False    ISECultureInfo              System.Globalization.CultureInfo                

This object has a number of methods and properties, as shown here:

PS C:\> get-culture | gm

   TypeName: Microsoft.Windows.PowerShell.Gui.Internal.ISECultureInfo

Name                           MemberType     Definition                                                       

—-                                ———-             ———-                                                       

ClearCachedData                Method     void ClearCachedData()                                           

Clone                          Method     System.Object Clone(), System.Object ICloneable.Clone()          

Equals                         Method     bool Equals(System.Object value)                                 

GetConsoleFallbackUICulture    Method     cultureinfo GetConsoleFallbackUICulture()                         

GetFormat                      Method     System.Object GetFormat(type formatType), System.Object IFormat…

GetHashCode                    Method     int GetHashCode()                                                

GetType                        Method     type GetType()                                                   

ToString                       Method     string ToString()                                                

Calendar                       Property   System.Globalization.Calendar Calendar {get;}                    

CompareInfo                    Property   System.Globalization.CompareInfo CompareInfo {get;}              

CultureTypes                   Property   System.Globalization.CultureTypes CultureTypes {get;}            

DateTimeFormat                 Property   System.Globalization.DateTimeFormatInfo DateTimeFormat {get;set;}

DisplayName                    Property   string DisplayName {get;}                                        

EnglishName                    Property   string EnglishName {get;}                                        

IetfLanguageTag                Property   string IetfLanguageTag {get;}                                    

IsNeutralCulture               Property   bool IsNeutralCulture {get;}                                     

IsReadOnly                     Property   bool IsReadOnly {get;}                                           

KeyboardLayoutId               Property   int KeyboardLayoutId {get;}                                       

LCID                           Property   int LCID {get;}                                                  

Name                           Property   string Name {get;}                                               

NativeName                     Property   string NativeName {get;}                                         

NumberFormat                   Property   System.Globalization.NumberFormatInfo NumberFormat {get;set;}    

OptionalCalendars              Property   System.Globalization.Calendar[] OptionalCalendars {get;}         

Parent                         Property   cultureinfo Parent {get;}                                        

TextInfo                       Property   System.Globalization.TextInfo TextInfo {get;}                    

ThreeLetterISOLanguageName     Property   string ThreeLetterISOLanguageName {get;}                         

ThreeLetterWindowsLanguageName Property   string ThreeLetterWindowsLanguageName {get;}                     

TwoLetterISOLanguageName       Property   string TwoLetterISOLanguageName {get;}                           

UseUserOverride                Property   bool UseUserOverride {get;}                                      

Notice that the TextInfo property actually contains another object. It is a TextInfo object from the System.Globalization namespace—the same namespace that contains the CultureInfo object.

The TextInfo object also has the following methods and properties associated with it:

PS C:\> ((get-culture).textinfo) | gm

   TypeName: System.Globalization.TextInfo

Name              MemberType      Definition                                                          

—-                    ———-            ———-                                                          

Clone             Method     System.Object Clone(), System.Object ICloneable.Clone()             

Equals            Method     bool Equals(System.Object obj)                                      

GetHashCode       Method     int GetHashCode()                                                   

GetType           Method     type GetType()                                                      

OnDeserialization Method     void IDeserializationCallback.OnDeserialization(System.Object sender)

ToLower           Method     char ToLower(char c), string ToLower(string str)                    

ToString          Method     string ToString()                                                    

ToTitleCase       Method     string ToTitleCase(string str)                                      

ToUpper           Method     char ToUpper(char c), string ToUpper(string str)                    

ANSICodePage      Property   int ANSICodePage {get;}                                             

CultureName       Property   string CultureName {get;}                                           

EBCDICCodePage    Property   int EBCDICCodePage {get;}                                            

IsReadOnly        Property   bool IsReadOnly {get;}                                              

IsRightToLeft     Property   bool IsRightToLeft {get;}                                           

LCID              Property   int LCID {get;}                                                      

ListSeparator     Property   string ListSeparator {get;set;}                                     

MacCodePage       Property   int MacCodePage {get;}                                              

OEMCodePage       Property   int OEMCodePage {get;}                                               

One of these methods is the ToTitleCase method. It accepts a string, and returns a string.

When we have a string object, we have access to string methods and properties. This is shown here:

PS C:\> (Get-Culture).textinfo.ToTitleCase($d.name) | Gm

   TypeName: System.String

Name             MemberType            Definition                                                          

—-                  ———-                   ———-                                                          

Clone            Method                System.Object Clone(), System.Object ICloneable.Clone()             

CompareTo        Method                int CompareTo(System.Object value), int CompareTo(string strB), in…

Contains         Method                bool Contains(string value)                                         

CopyTo           Method                void CopyTo(int sourceIndex, char[] destination, int destinationIn…

EndsWith         Method                bool EndsWith(string value), bool EndsWith(string value, System.St…

Equals           Method                bool Equals(System.Object obj), bool Equals(string value), bool Eq…

GetEnumerator    Method                System.CharEnumerator GetEnumerator(), System.Collections.IEnumera…

GetHashCode      Method                int GetHashCode()                                                   

GetType          Method                type GetType()                                                      

GetTypeCode      Method                System.TypeCode GetTypeCode(), System.TypeCode IConvertible.GetTyp…

IndexOf          Method                int IndexOf(char value), int IndexOf(char value, int startIndex), …

IndexOfAny       Method                int IndexOfAny(char[] anyOf), int IndexOfAny(char[] anyOf, int sta…

Insert           Method                string Insert(int startIndex, string value)                         

IsNormalized     Method                bool IsNormalized(), bool IsNormalized(System.Text.NormalizationFo…

LastIndexOf      Method                int LastIndexOf(char value), int LastIndexOf(char value, int start…

LastIndexOfAny   Method                int LastIndexOfAny(char[] anyOf), int LastIndexOfAny(char[] anyOf,…

Normalize        Method                string Normalize(), string Normalize(System.Text.NormalizationForm…

PadLeft          Method                string PadLeft(int totalWidth), string PadLeft(int totalWidth, cha…

PadRight         Method                string PadRight(int totalWidth), string PadRight(int totalWidth, c…

Remove           Method                string Remove(int startIndex, int count), string Remove(int startI…

Replace          Method                string Replace(char oldChar, char newChar), string Replace(string …

Split            Method                string[] Split(Params char[] separator), string[] Split(char[] sep…

StartsWith       Method                bool StartsWith(string value), bool StartsWith(string value, Syste…

Substring        Method                string Substring(int startIndex), string Substring(int startIndex,…

ToBoolean        Method                bool IConvertible.ToBoolean(System.IFormatProvider provider)        

ToByte           Method                byte IConvertible.ToByte(System.IFormatProvider provider)           

ToChar           Method                char IConvertible.ToChar(System.IFormatProvider provider)           

ToCharArray      Method                char[] ToCharArray(), char[] ToCharArray(int startIndex, int length)

ToDateTime       Method                datetime IConvertible.ToDateTime(System.IFormatProvider provider)   

ToDecimal        Method                decimal IConvertible.ToDecimal(System.IFormatProvider provider)     

ToDouble         Method                double IConvertible.ToDouble(System.IFormatProvider provider)       

ToInt16          Method                int16 IConvertible.ToInt16(System.IFormatProvider provider)         

ToInt32          Method                int IConvertible.ToInt32(System.IFormatProvider provider)           

ToInt64          Method                long IConvertible.ToInt64(System.IFormatProvider provider)          

ToLower          Method                string ToLower(), string ToLower(cultureinfo culture)               

ToLowerInvariant Method                string ToLowerInvariant()                                           

ToSByte          Method                sbyte IConvertible.ToSByte(System.IFormatProvider provider)         

ToSingle         Method                float IConvertible.ToSingle(System.IFormatProvider provider)        

ToString         Method                string ToString(), string ToString(System.IFormatProvider provider…

ToType           Method                System.Object IConvertible.ToType(type conversionType, System.IFor…

ToUInt16         Method                uint16 IConvertible.ToUInt16(System.IFormatProvider provider)       

ToUInt32         Method                uint32 IConvertible.ToUInt32(System.IFormatProvider provider)       

ToUInt64         Method                uint64 IConvertible.ToUInt64(System.IFormatProvider provider)       

ToUpper          Method                string ToUpper(), string ToUpper(cultureinfo culture)               

ToUpperInvariant Method                string ToUpperInvariant()                                           

Trim             Method                string Trim(Params char[] trimChars), string Trim()                 

TrimEnd          Method                string TrimEnd(Params char[] trimChars)                             

TrimStart        Method                string TrimStart(Params char[] trimChars)                           

Chars            ParameterizedProperty char Chars(int index) {get;}                                        

Length           Property              int Length {get;}                                                    

One of these string methods is the Split method. It also returns a string:

PS C:\> (Get-Culture).textinfo.ToTitleCase($d.name).split(',') | gm

   TypeName: System.String

Name             MemberType            Definition                                                          

—-                  ———-                   ———-                                                          

Clone            Method                System.Object Clone(), System.Object ICloneable.Clone()             

CompareTo        Method                int CompareTo(System.Object value), int CompareTo(string strB), in…

Contains         Method                bool Contains(string value)                                          

CopyTo           Method                void CopyTo(int sourceIndex, char[] destination, int destinationIn…

EndsWith         Method                bool EndsWith(string value), bool EndsWith(string value, System.St…

Equals           Method                bool Equals(System.Object obj), bool Equals(string value), bool Eq…

GetEnumerator    Method                System.CharEnumerator GetEnumerator(), System.Collections.IEnumera…

GetHashCode      Method                int GetHashCode()                                                    

GetType          Method                type GetType()                                                      

GetTypeCode      Method                System.TypeCode GetTypeCode(), System.TypeCode IConvertible.GetTyp…

IndexOf          Method                int IndexOf(char value), int IndexOf(char value, int startIndex), …

IndexOfAny       Method                int IndexOfAny(char[] anyOf), int IndexOfAny(char[] anyOf, int sta…

Insert           Method                string Insert(int startIndex, string value)                         

IsNormalized     Method                bool IsNormalized(), bool IsNormalized(System.Text.NormalizationFo…

LastIndexOf      Method                int LastIndexOf(char value), int LastIndexOf(char value, int start…

LastIndexOfAny   Method                int LastIndexOfAny(char[] anyOf), int LastIndexOfAny(char[] anyOf,…

Normalize        Method                string Normalize(), string Normalize(System.Text.NormalizationForm…

PadLeft          Method                string PadLeft(int totalWidth), string PadLeft(int totalWidth, cha…

PadRight         Method                string PadRight(int totalWidth), string PadRight(int totalWidth, c…

Remove           Method                string Remove(int startIndex, int count), string Remove(int startI…

Replace          Method                string Replace(char oldChar, char newChar), string Replace(string …

Split            Method                string[] Split(Params char[] separator), string[] Split(char[] sep…

StartsWith       Method                bool StartsWith(string value), bool StartsWith(string value, Syste…

Substring        Method                string Substring(int startIndex), string Substring(int startIndex,…

ToBoolean        Method                bool IConvertible.ToBoolean(System.IFormatProvider provider)        

ToByte           Method                byte IConvertible.ToByte(System.IFormatProvider provider)           

ToChar           Method                char IConvertible.ToChar(System.IFormatProvider provider)           

ToCharArray      Method                char[] ToCharArray(), char[] ToCharArray(int startIndex, int length)

ToDateTime       Method                datetime IConvertible.ToDateTime(System.IFormatProvider provider)   

ToDecimal        Method                decimal IConvertible.ToDecimal(System.IFormatProvider provider)     

ToDouble         Method                double IConvertible.ToDouble(System.IFormatProvider provider)       

ToInt16          Method                int16 IConvertible.ToInt16(System.IFormatProvider provider)         

ToInt32          Method                int IConvertible.ToInt32(System.IFormatProvider provider)           

ToInt64          Method                long IConvertible.ToInt64(System.IFormatProvider provider)          

ToLower          Method                string ToLower(), string ToLower(cultureinfo culture)               

ToLowerInvariant Method                string ToLowerInvariant()                                            

ToSByte          Method                sbyte IConvertible.ToSByte(System.IFormatProvider provider)         

ToSingle         Method                float IConvertible.ToSingle(System.IFormatProvider provider)        

ToString         Method                string ToString(), string ToString(System.IFormatProvider provider…

ToType           Method                System.Object IConvertible.ToType(type conversionType, System.IFor…

ToUInt16         Method                uint16 IConvertible.ToUInt16(System.IFormatProvider provider)       

ToUInt32         Method                uint32 IConvertible.ToUInt32(System.IFormatProvider provider)       

ToUInt64         Method                uint64 IConvertible.ToUInt64(System.IFormatProvider provider)       

ToUpper          Method                string ToUpper(), string ToUpper(cultureinfo culture)               

ToUpperInvariant Method                string ToUpperInvariant()                                           

Trim             Method                string Trim(Params char[] trimChars), string Trim()                 

TrimEnd          Method                string TrimEnd(Params char[] trimChars)                             

TrimStart        Method                string TrimStart(Params char[] trimChars)                           

Chars            ParameterizedProperty char Chars(int index) {get;}                                        

Length           Property              int Length {get;}                                                     

The Split method returns a string, and one of those methods is the Trim method, which you can see here:

PS C:\> (Get-Culture).textinfo.ToTitleCase($d.name).split(',') | gm

   TypeName: System.String

Name             MemberType            Definition                                                          

—-                   ———-                   ———-                                                          

Clone            Method                System.Object Clone(), System.Object ICloneable.Clone()             

CompareTo        Method                int CompareTo(System.Object value), int CompareTo(string strB), in…

Contains         Method                bool Contains(string value)                                         

CopyTo           Method                void CopyTo(int sourceIndex, char[] destination, int destinationIn…

EndsWith         Method                bool EndsWith(string value), bool EndsWith(string value, System.St…

Equals           Method                bool Equals(System.Object obj), bool Equals(string value), bool Eq…

GetEnumerator    Method                System.CharEnumerator GetEnumerator(), System.Collections.IEnumera…

GetHashCode      Method                int GetHashCode()                                                   

GetType          Method                type GetType()                                                      

GetTypeCode      Method                System.TypeCode GetTypeCode(), System.TypeCode IConvertible.GetTyp…

IndexOf          Method                int IndexOf(char value), int IndexOf(char value, int startIndex), …

IndexOfAny       Method                int IndexOfAny(char[] anyOf), int IndexOfAny(char[] anyOf, int sta…

Insert           Method                string Insert(int startIndex, string value)                         

IsNormalized     Method                bool IsNormalized(), bool IsNormalized(System.Text.NormalizationFo…

LastIndexOf      Method                int LastIndexOf(char value), int LastIndexOf(char value, int start…

LastIndexOfAny   Method                int LastIndexOfAny(char[] anyOf), int LastIndexOfAny(char[] anyOf,…

Normalize        Method                string Normalize(), string Normalize(System.Text.NormalizationForm…

PadLeft          Method                string PadLeft(int totalWidth), string PadLeft(int totalWidth, cha…

PadRight         Method                string PadRight(int totalWidth), string PadRight(int totalWidth, c…

Remove           Method                string Remove(int startIndex, int count), string Remove(int startI…

Replace          Method                string Replace(char oldChar, char newChar), string Replace(string …

Split            Method                string[] Split(Params char[] separator), string[] Split(char[] sep…

StartsWith       Method                bool StartsWith(string value), bool StartsWith(string value, Syste…

Substring        Method                string Substring(int startIndex), string Substring(int startIndex,…

ToBoolean        Method                bool IConvertible.ToBoolean(System.IFormatProvider provider)        

ToByte           Method                byte IConvertible.ToByte(System.IFormatProvider provider)           

ToChar           Method                char IConvertible.ToChar(System.IFormatProvider provider)           

ToCharArray      Method                char[] ToCharArray(), char[] ToCharArray(int startIndex, int length)

ToDateTime       Method                datetime IConvertible.ToDateTime(System.IFormatProvider provider)   

ToDecimal        Method                decimal IConvertible.ToDecimal(System.IFormatProvider provider)     

ToDouble         Method                double IConvertible.ToDouble(System.IFormatProvider provider)       

ToInt16          Method                int16 IConvertible.ToInt16(System.IFormatProvider provider)         

ToInt32          Method                int IConvertible.ToInt32(System.IFormatProvider provider)           

ToInt64          Method                long IConvertible.ToInt64(System.IFormatProvider provider)          

ToLower          Method                string ToLower(), string ToLower(cultureinfo culture)               

ToLowerInvariant Method                string ToLowerInvariant()                                           

ToSByte          Method                sbyte IConvertible.ToSByte(System.IFormatProvider provider)         

ToSingle         Method                float IConvertible.ToSingle(System.IFormatProvider provider)        

ToString         Method                string ToString(), string ToString(System.IFormatProvider provider…

ToType           Method                System.Object IConvertible.ToType(type conversionType, System.IFor…

ToUInt16         Method                uint16 IConvertible.ToUInt16(System.IFormatProvider provider)       

ToUInt32         Method                uint32 IConvertible.ToUInt32(System.IFormatProvider provider)       

ToUInt64         Method                uint64 IConvertible.ToUInt64(System.IFormatProvider provider)       

ToUpper          Method                string ToUpper(), string ToUpper(cultureinfo culture)               

ToUpperInvariant Method                string ToUpperInvariant()                                           

Trim             Method                string Trim(Params char[] trimChars), string Trim()                 

TrimEnd          Method                string TrimEnd(Params char[] trimChars)                              

TrimStart        Method                string TrimStart(Params char[] trimChars)                           

Chars            ParameterizedProperty char Chars(int index) {get;}                                        

Length           Property              int Length {get;}                                                    

So, it would be possible to rewrite the one line of code in about five other lines. It might appear like this:

$culture = (Get-Culture)

$txtInfo = $culture.textinfo

$titleCase = $textInfo.ToTitleCase($d.name)

$splitTitle = $titleCase.Split(',')

$trimedSplitTitle = $splitTitle.trim() 

But in reality, I am not sure that code is easier to read. In fact, for me it is not easier to read. It might be better for beginners, so that they can easily see what object they are dealing with at each stage of the progression; but otherwise, it really doesn’t make sense to use five different variables for each stage of the progression. In fact, after you learn how to read the code, it makes sense to present it on a single line.

There is no Windows PowerShell cmdlet that will do this for you. So if you want to groom the string, you need to write a complicated RegEx expression or use these string methods. For me, the string methods are easier to understand.

Now you know how to use Windows PowerShell to work with strings. Join me tomorrow when I will talk about more cool stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

0 comments

Discussion is closed.

Feedback usabilla icon