Home > Software engineering >  Powershell - last two characters in the text line
Powershell - last two characters in the text line

Time:03-26

I would appreciate if someone point me in a right direction.

Task(s) ----------

  1. Split the string and assign folder path (note blank spaces in the path) to different variables.

OR

  1. Get lines from text file and extract last 2 characters ignoring blank spaces between folder path and assigned drive letter.

Example of a text file ----------

\FileServer\movetest\somefiles Z:
\FileServer\mogul MOVE OUT\anotherfiles Y:

Attempt to code ---------- 1)

 $getDriveLines = gc -Path $inputFile    

foreach( $_ in $getDriveLines)                                                                    { 
   [stringsplitoptions]$option = "removeEmptyEntries" $oldFILEPath = $_.split(" ",$option)[0]
   Write-Host ("Old FS path is ") $oldFILEPath

   $constantFILEDriveLetter = $_.split(" ",$option)[1]
   Write-Host ("Constant FS Letter is ") $constantFILEDriveLetter }

Problem ---------- please note that it splits folder path (3rd line) and shows in last line of output part of a "folder path" and not the drive letter.

      Old FS path is  \\FileServer\\movetest\\somefiles

Constant FS Letter is Z: Old FS path is \FileServer\mogul Constant FS Letter is MOVE

)

$getDriveLines = gc -Path $inputFile

  foreach( $Line in $getDriveLines)

{

$value = $Line.Substring($Line.Length - 2)

 }

Problem ---------- it displays the following, please NOTE that there is no value displayed for "Z:" second line

   \\\\FileServer\\movetest\\somefiles          Z:  
     The value is -  
   \\\\FileServer\\mogul MOVE OUT\\anotherfiles Y:

The value is - Y:

Is it overwritten ? What this code is missing ?

CodePudding user response:

Your post was hard to read but reading your headline i might have a script that will help you

foreach ( $line in (Get-Content -Path $inputFile)) { 
   $oldFILEPath = $line.Substring(0,$line.length -3)
   $constantFILEDriveLetter = $line.Substring($line.length -2, 2)

   Write-Output "Old FS path is `"$oldFILEPath`""
   Write-Output "Constant FS letter is $constantFILEDriveLetter`r`n"
}

Result looks like

Old FS path is "\FileServer\movetest\somefiles"
Constant FS letter is Z:

Old FS path is "\FileServer\mogul MOVE OUT\anotherfiles"
Constant FS letter is Y:

CodePudding user response:

  • There is no easy solution with the .Split() .NET method, which operates on literal separator strings, but concise solutions are possible with the regex-based -split operator - see below.

  • Your .Substring() approach - $value = $Line.Substring($Line.Length - 2) to get the drive spec. - was likely only hampered by trailing spaces in the first line of your input file, which you could easily fix as follows:

    $getDriveLines = (gc -Path $inputFile).Trim()
    

In PowerShell (Core) 7 there is a straightforward solution, using the -split operator with a negative token count, specifically -2:

(Get-Content $inputFile).Trim() | ForEach-Object {
  $path, $drive = $_ -split '  ', -2
  # Sample output
  [pscustomobject] @{
    Path = $path
    Drive = $drive
  }
}
  • Regex ' ' matches one or more ( ) spaces (' ').

  • -2 tells -split to return at most 2 tokens from the end, due to the number being negative. This causes the splitting to effectively be performed only at the last run of spaces in the input string, so that the path preceding the drive spec. at the end is preserved as-is, even if it contains spaces too.

Output:

Path                                       Drive
----                                       -----
\\FileServer\\movetest\\somefiles          Z:
\\FileServer\\mogul MOVE OUT\\anotherfiles Y:

In Windows PowerShell, where negative token counts aren't supported, a concise solution is a bit more complex:

(Get-Content $inputFile).Trim() | ForEach-Object {
  $path, $drive = $_ -split '  (?=[a-z]:$)'
  # Sample output
  [pscustomobject] @{
    Path = $path
    Drive = $drive
  }
}
  • Here too it is ensured that the input string is only split by the last run of spaces, by using a (positive) look-ahead assertion ((?=...)) that only matches a run of spaces (' ') if it is followed by subexpression that matches a drive spec. ([a-z]:) at the end of the string ($).
  • Related