2

I have a string with different length. I want to cut a specific word in my string. Please help, I am new to PowerShell.

I tried this code, it's still not what I need.

$String = "C:\Users\XX\Documents\Data.txt"
$Cut = $String.Substring(22,0)
$Cut

My expectation is that I can return the word Data.

Robert Dyjas
  • 4,979
  • 3
  • 19
  • 34
Cheries
  • 834
  • 1
  • 13
  • 32

5 Answers5

4

Assuming the string is always the same format (i.e. a path ending in a filename), then there are quite a few ways to do this, such as using regular expressions. Here is a slightly less conventional method:

# Define the path
$filepath = "C:\Users\XX\Documents\Data.txt"

# Create a dummy fileinfo object
$fileInfo = [System.IO.FileInfo]$filePath

# Get the file name property
$fileInfo.BaseName

Of course, you could do all of this in one step:

([System.IO.FileInfo]"C:\Users\XX\Documents\Data.txt").BaseName
boxdog
  • 7,894
  • 2
  • 18
  • 27
  • Regular expression is not meant for this. There is a C# method [Path.GetFileNameWithoutExtension](https://learn.microsoft.com/en-us/dotnet/api/system.io.path.getfilenamewithoutextension) for that. – Bakudan Jun 10 '19 at 12:17
  • _"Regular expression is not meant for this"_ @Bakudan, what are regular expressions meant for? – boxdog Jun 10 '19 at 12:30
  • The point is there are functions intended exactly for file paths. Regex is better for text processing. As per [wikipedia](https://en.wikipedia.org/wiki/Regular_expression#Uses) "Common applications include data validation, data scraping (especially web scraping), data wrangling, simple parsing, the production of syntax highlighting systems, and many other tasks." – Bakudan Jun 10 '19 at 20:19
  • _"Regex is better for text processing"_ @Bakudan I am fully aware that [RegEx isn't always the best tool for the job](https://blog.codinghorror.com/regular-expressions-now-you-have-two-problems/). That's probably why I didn't actually advocated it, only mentioning it as one of many possibilities (cf. the other answers to this question). The main intention of my answer was to show a different approach for the questioner to consider - much like you give one approach in an actual answer, and another here in the comments. – boxdog Jun 11 '19 at 08:22
2

If the path is an existing one, you could use

(Get-Item $String).BaseName

Otherwise

(Split-Path $String -Leaf) -Replace '\.[^\.]*$'
1

While in that specific example the simplest way is to use Substring(startPosition,length) to extract file name you'd probably want to use something like this:

(("C:\Users\XX\Documents\Data.txt".split("\\"))[-1].Split("."))[0]

Explanation:

("C:\Users\XX\Documents\Data.txt".split("\\"))[-1]

that part split the path by \ and returns last item (escaping it seems to be not mandatory by the way so you can use .split("\") instead of .split("\\")). From it you receive Data.txt so you have to separate name and extension. You can do this by splitting by . and choosing first element returned

Robert Dyjas
  • 4,979
  • 3
  • 19
  • 34
1

There are number of ways of doing it depending upon your input -

Method 1 - Hard-coding using the sub-string function.

$String = "C:\Users\XX\Documents\Data.txt"
$Cut = $String.Substring(22,4)
$Cut

The above approach will work for a single input but will become difficult to manage for multiple inputs of different lengths.

Method 2 - Using the split method

$String = "C:\Users\XX\Documents\Data.txt"
$cut = $String.Split("\")[-1].split(".")[0]
$cut

Split method will split string into substring. The index [-1] will return the last value returned by the split method. The second split is to return the word Data from the word Data.txt.

Method 3 - If the input is a file path

$string = Get-ChildItem $env:USERPROFILE\Desktop -File | select -First 1
$Cut = $String.BaseName

More about method 3 here.

Vivek Kumar Singh
  • 3,223
  • 1
  • 14
  • 27
1

If you can use Powershell 6 - SplitPath

#Requires -Version 6.0
Split-Path $String -LeafBase
Bakudan
  • 19,134
  • 9
  • 53
  • 73