0

UPDATED/REWRITTEN QUESTION

The following is a re-write of a question some found to be confusing. However, I am re-writing this question after learning what I hoped to accomplish was not possible. But, I have provided a workaround as an answer in case another may have a similar question in the future.

Also, if reading comments and you see reference to $base, that variable was originally used. However, as this question/answer became more robust, $base was replaced with $variable to make it more generic and hopefully prevent confusion by some future reader asking, what is $base. $base and its replacement $var are strings.


I have IF-THEN conditions that often contain four or more conditions. As a result, the IF statement gets very "busy" and difficult to decipher when creating subsequent conditions (i.e. ELSEIF, etc.). This makes it more difficult to ensure I am writing the conditional statements to produce the output I intend.

For instance, I have the following IF statement in a script:

if ((Test-Path -Path "$variable") -eq $true -and $variable.trim().substring(1,1) -eq ':'-and $variable.trim().len() -le 3 -and $variable.trim().len() -ge 2)
{
    <some commands>
}

What I would like to do is determine if there is some syntax (i.e. a one-liner) that I can use to shorten some of the longer commands. Update note: the following is not possible but a workaround is in the answer below.

For instance, I would like shorten $variable.trim().substring(1,1) so that it is easier to read (i.e. takes up less screen space). However, I still want it to be dynamic with respect to the .substring() portion. So, is there some syntax that I could create that looked like $varSubStr([int32],[int32]) that is equal to $bast.trim().substring([int32],[int32])?

So, whenever I needed a substring of $variable, I could call $varSubStr(1,1). (update note: what I am trying to is create a function - I just didn't realize that at the time of writing this question).

So, when I write the same IF statement from above, it is shortened by substituting $varSubStr(1,1) for $variable.trim().substring(1,1). However, it would still be dynamic so I could change the values for the substring. The new IF statement would look like:

if ((Test-Path -Path "$variable") -eq $true -and $varSubStr(1,1) -eq ':'-and $variable.trim().len() -le 3 -and $variable.trim().len() -ge 2)
{
    <some commands>
}

In the same vain, I could shorten $variable.trim().length() to $varLen. I should point out that $variable variable can change as it is processed in the script; so $varLen would need to dynamically update when called (update note: again, what I was describing is a function - I just didn't realize it at the time).

Then the IF statement might look something like:

if ((Test-Path -Path "$variable") -eq $true -and $varSubStr(1,1) -eq ':'-and $varLen -le 3 -and $varLen -ge 2)
{
    <some commands>
}

This is much shorter and easier to read.

So, is there a one-liner syntax of some sort in PowerShell that would accomplish this (update note: the answer is no; what is needed is a function)?

UPDATE NOTE (for a novice who may be reading this): A variable $var is a static object that does not dynamically update. Unless you set a new value $var=<some value> it will not dynamically update. When I am referring to $varSubStr() or $varLen I am simply using them as placeholders in my attempt to describe what I would like my output to look like. Please do not think variables are dynamically updated. If you need things to be dynamically update, you need to create a function.


ORIGINAL POST AS WRITTEN


Is there a syntax that makes the following possible in PowerShell - namely what can I change the line starting $b to to make that line actually work?

# Start Script

[string]$ReallyLongVariableNameThatIsUsefulAsADescription="AStringThatRunsOnandOnandOn"

$b=$ReallyLongVariableNameThatIsUsefulAsADescription.trim().substring

Write-Output $b(0,8)

# End Script

PS c:\<script.ps1>

AStringT

PS c:\

I realize that I could create a short function that accomplishes the task I am wondering if there is a one-liner solution like what illustrated above.

Thanks.

  • i confess that i don't understand what you are trying to do. [blush] would you please try another description - perhaps with lots of examples? – Lee_Dailey Apr 19 at 5:30
  • 1
    The docs specifically sate what is possible, and If I understand what you are after, that is nowhere covered in the specifications. If you want to do things, not in the specs, then proxy / custom code is required. Variables are specifically designed to hold content as long as it is not null. Like Lee says, I really can't think fo a use case for this type of thing. – postanote Apr 19 at 22:18
  • Thanks, @postanote. That is what I figured as I continued to search. I settled on converting the variable to a function with three parameters as the solution. – Brian Apr 19 at 23:17
  • @Lee_Daily, my "solution" below may better illustrate what I wanted to accomplish. Sorry my description wasn't better. I will try editing my original question so that if someone stumbles across this post in the future it makes more sense. – Brian Apr 19 at 23:17
1

As @postanote said, a variable is a static value and it cannot be dynamically changed.

The solution I was looking for was functions. I can effectively create a one-liner that I can put into my IF statements that will call a function which uses current values of static variables and returns the new values I need to evaluate at that moment in the script.

So, to make it clear, the "dynamic variables" I wanted to create in my question have a solution in the form of a PowerShell function. Using functions is the solution.


Solution/Workaround Using Functions


My fundamental problem was that adding .trim().substring([int32],[int32]) and .trim().len() to variables was making my code look busy and harder to decipher. I wanted to shorten the number of characters required to call $variable.trim().substring([int32],[int32]).

With functions, I can create a command such as (varSubStr [int32] [int32]) that when called, evaluates, $variable.trim().substring([int32],[int32]) and returns its value.

For my solution/workaround, I settled on using three functions; one function was external to the script I was working on (as it is used by other scripts) and two functions were embedded within the script. Creating these functions made reading long IF statements easier.

Originally, within my script, I would have lines that looked like this:

###### START OF SCRIPT 

###### Various commands within the script

if ((Test-Path -Path "$variable") -eq $true -and $variable.trim().substring(1,1) -eq ':'-and $variable.trim().len() -le 3 -and $variable.trim().len() -ge 2)
{
    <some commands>
}

###### Various commands within the script

###### END OF SCRIPT

This made deciphering the conditional logic tedious. The tedium made it more challenging to determine if the logic of this conditional statement acted upon variables in the way intended within that IF block of the IF-THEN statement.

Ultimately the above IF block will appear as the following when functions are used to accomplish the same tasks as the IF-THEN statement above:

if ((Test-Path -Path "$variable") -eq $true -and (varSubStr_1_1) -eq ':'-and (varLen) -le 3 -and (varLen) -ge 2)
{
    <some commands>
}

In the above IF statement, the functions that replace functions $variable.trim().substring(1,1) and $variable.trim().len() are varSubStr_1_1 and varLen, respectively. These functions are defined below:

###### The following function, `Get-TrimThenSubStr` is defined outside
###### the scope of my script. It is included here as it is referenced
###### in the embedded functions in my script. 

# The following function, `Get-TrimThenSubStrTrim`requires the user to 
# enter three parameters $InputString,$StartPositiotnstring,$EndPosition
# and return a substring from the `$InputString`

# Function Syntax: Get-TrimThenSubStr -InputString [string]$InputString -StartPosition [int32]$StartPositionOfSubstring -EndPosition [int32]$EndPositionOfSubString

##### Note: This function, Get-TrimThenSubStr, is referenced by the embedded function, varSubStr_1_1, that I define below inside the main script.

function Get-TrimThenSubStr
{
    [CmdletBinding()]
    [Alias("TrimSubStr","TrSubStr","TrimThenSubString")]
    param 
    (
        [Parameter(Mandatory=$true)][Alias("Input")][string]$InputString,
        [Parameter(Mandatory=$true)][Alias("Start")][int32]$StartPosition,
        [Parameter(Mandatory=$true)][Alias("End")][int32]$NumberOfCharacters
    )

    $input=$InputString
    $start=$StartPosition
    $char=$NumberOfCharacters

    if (!($start -match "^[\d\.]+$")) {$start=(Invoke-Expression "$start")}
    if (!($char-match "^[\d\.]+$")) {$char=(Invoke-Expression "$char")}

    return $input.Trim().Substring($start,$char)
}

MyScript
{

###### START OF SCRIPT

###### IMPORTANT NOTE
###### The variable, $variable, is defined and used throughout the script
###### prior to it being called by the functions below or IF-THEN statements.

# The following script, varLen, is embedded in this script and not
# accessible outside this script.
# The function, varLen, returns the length of the string, $variable
# Syntax: varLen

###### Note: this is an embedded functions that acts upon variables
###### defined in myScript (i.e. $variable). As such it is designed
###### without input parameters.

function varLen 
{
    return "$variable".trim().Length
}

# The following function, varSubStr_1_1, is embedded in this script
# and not accessible outside this script.
# This script relies on the external function, Get-TrimThenSubStr,
# to execute.
# The function, varSubStr_1_1, below, will return a substring from
# $variable starting at position 1 and for 1 character.
# Syntax: varSubStr_1_1
###### Note: this is an embedded function that acts upon variables
###### defined in MyScript (i.e. $variable). As such it is designed
###### without parameters
###### Note: While this function is very narrow, its primary purpose is
###### to make it easier to read conditions within an 
###### IF-THEN statement - not add functionality

function varSubStr_1_1 
{
    # Call the function, varLen, to get $variable length
    if ((varLen) -lt 2)
    {
        return $variable
    }
    else
    {
        # Call external function, Get-TrimThenSubstr, and enter parameters
        # -InputString <$variable> -StartPosition <1> -EndPosition <1>
        return Get-TrimThenSubStr -InputString $variable -StartPosition 1 -EndPosition 1
    }
}

###### Various commands/logic within MyScript

# In the following IF-Then statement, the functions, varSubStr_1_1 and
# varLen can be substituted in place of ($variable.trim().substring(1,1))
# and ($variable.trim().len()), respectively

if ((Test-Path -Path "$variable") -eq $true -and (varSubStr_1_1) -eq ':'-and (varLen) -le 3 -and (varLen) -ge 2)
{
    <some commands>
}
else
{
    <some commands>
}

###### Various commands/logic within MyScript

###### END OF SCRIPT

Creating the function varSubStr_1_1 (which relied on external script, Get-TrimThenSubStr) and varLen were the "one-liners" I wanted to shorten the number of characters within an IF-THEN statement so it would be easier to digest when reading.


Lastly, if I wanted to further shorten the contents within the IF statement, I realize there are a few other things I could do such as:

  • Eliminate -eq $true from (Test-Path -Path $variable") -eq $true since (Test-Path -Path $variable") evaluates to $true or $false. However, for me, I find it quicker to interpret by explicitly adding the -eq $true condition.
  • A function for (Test-Path -Path $variable) like (PathExists) would further shorten text.
  • (varSubStr_1_1 -eq ":") could be further shortened by evaluating -eq ":" within the function and return $true or $false and then rename it something like: varSubStr_1_1_SemiColon

Doing such improvements, I could get something like:

if ((PathExists) -and (varSubStr_1_1_IsSemiColon) -and (varLen) -le 3 -and (varLen) -ge 2)

Now, that I write this, I may just end up doing that. I realize it takes more CPU time but that is irrelevant for what the script ultimately does.


UPDATE


I did end up adding some addition functions to make IF-THEN easier to read. For instance:

if ((varPathExists) -and (varLenInclsvOf 2 2) -and (varSubStr_1_1_Is:_:))

where (varPathExists),(varLenInclsOf [int32][ [int32]), and (varSubStr_1_1_Is:_:) are functions that return a boolean value.

While I will not break down each function, the only one that may not be self-explantory is (varLenInvlsOf). (varLenInvlsOf) is a shortening of the phrase, "variable length is inclusive of." It requires two parameters which are [int32] after it to indicate when the substring begins and ends, inclusive of those numbers.

So, in short, this solution/workout really talks about how functions can be used to shorten longer commands variables. Obviously, if you use too many functions, it can get just as confusing. But, in my case, it worked and helped to make many, many logical IF-THEN statements easier to digest and avoid errors.

| improve this answer | |
  • if ((Test-Path -Path "$base") -eq $true is redundant. Test-Path returns a boolean. – Keith Miller Apr 20 at 0:31
  • @KeithMiller: I am a little confused about what in the above you are hinting at as needing corrected or as a possible alternative. Test-Path by itself does nothing as it requires parameters. (Test-Path -Path [string]) returns a boolean result. So ((Test-Path -Path "$base") -eq $true) will evaluate to ((<boolean result>) -eq $true) to then be evaluated against each other. So it either reduces to ($true -eq $true) --> $true or ($false -eq $true) --> $false. Thus, ((Test-Path -Path "$base")) is sufficient without -eq $true. (Test-Path) alone is useless – Brian Apr 20 at 0:43
  • (Test-Path -Path "$base") is all you need. The ...-eq $True is unnecessary. – Keith Miller Apr 20 at 0:47
  • @KeithMiller: I see what you are saying. I was confused because I had cited that exact thing at the end of my "solution" as bullet point 1. So, I thought you were pointing out something new. But, like me, I imagine most just peruse the highlights and get bored by the end of a longer solution. I included those thoughts at the end in case someone in the future is using this post as a guide to solve their own problems. – Brian Apr 20 at 0:53
  • To be honest, I still don't understnad your original question nor the nature of your solution. I was scanning for syntax and trying to get a handle on what you are thinking... – Keith Miller Apr 20 at 1:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.