Read first line of text in txt file them cut charters 5-10 to a variable

I am working on a script that will read the first line of text in a txt file then take that line and cut charters 5 through 15 and then out those cut charters into a variable to use later.
I am thinking that Get-Content is the way to go but having a hard time with the cut to variable part.


$var = Get-Content -Path C:\temp\testfile.txt
$var2 = $var.Substring(5,15)

I think :smiley:
you may have to index [0] if there are multiple lines


You are not limiting your content to the first line so $var is actually an array of lines from the input file. substring does not work on arrays. You need to limit to the first line of the file content. Easy way is to use select-object.

$var = Get-Content -Path C:\temp\testfile.txt | Select-Object -First 1

yup I realized that thanks Curtis you always teach me something new.

Ah you got an edit in there while I was posting. Using the array position will work, but that means you have to load the full content of the file. Using Select-Object, it will stop reading the file after the select criteria has been met.

Tag, you’re it :slight_smile:

If you use that method, your array position should be defined on your input file variable “$var”. It holds the array that has the content of the file.

$var = Get-Content -Path C:\temp\testfile.txt
$var2 = $var[0].Substring(5,15)

well I knew about select-object -first but did not know it would select the first line. At first I thought get-content would treat the file as one big text string did not know new lines would be treated as objects. I love this stuff you just keep on learning new things.

lol I was trying to do that but I was doing this $var2 = $var.Substring(5,15)[0]

one of those times I was writing the code in the chat window rather then using powershell.

I sense I am making a mess of this.
Here is my code so far

$FileLocation = "D:\Files"

$File1Temp = Get-ChildItem $FileLocation -Filter File1.txt.*
$File2Temp = Get-ChildItem $FileLocation -Filter File2.txt.*
$File3Temp = Get-ChildItem $FileLocation -Filter File3.txt.*

$File1ProcDate = Get-Content -Path "$FileLocation\$File1Temp" -TotalCount 1
$File1Rem = $File1ProcDate.Substring(32,39)
Rename-Item -Path "$FileLocation\$File1Temp" File1.txt.$File1Rem"
$File2ProcDate = Get-Content -Path "$FileLocation\$File2Temp" -TotalCount 1
$File2Rem = $File2ProcDate.Substring(43,50)
Rename-Item -path "$FileLocation\$File2Temp" "File2.txt.$File2Rem"
$File3ProcDate = Get-Content -Path "$FileLocation\$File3Temp" -TotalCount 1
$File3Rem = $File3ProcDate.Substring(31,38)
Rename-Item -Path "$FileLocation\$File3Temp" "File3.txt.$File3Rem"

Basicly what I am trying to accomplish is I have a folder where 3 files are sent to with a random number appended top the file name. I am trying to replace that random number with the files processing date which is found with in the first line of text.

Many thinks for the help!!!

Nathan, can your add the pre and /pre tags around your code so it can be more easily read and worked with?

I can fix it for you when I get to work tomorrow. For the rename look at split-path or look at the properties of the variable when you assign it will be something like $file1temp.filename you can the do a simple rename

Quick question. What is the format of the date in the TXT file? Frequently it will contain invalid characters for file names such as the / character or the : character. You will need to remove or replace invalid characters before your rename can occur.

the date is just in a string of numbers. Example: 20151130

Thanks a bunch!!

If the date is in the same location in each files this will do all three. However it may hit on some unwanted files I have not learned yet how to add regex but this is the pattern for

$FileLocation = "D:\Files"

$FileTemp = Get-ChildItem -Path $FileLocation | ?{$_ -like "File*"}

foreach($File in $FileTemp){
$FileProcDate = Get-Content -Path $File.FullName -First 1
$FileRem = $FileProcDate.Substring(5,15)
Rename-Item -Path $File.FullName  (Join-Path $FileLocation "$($FileRem)File1.txt")

Good example Mark

Here is how you can do it when the date is in a different position for each numbered file. One thing to note in Nathan’s code is the use of substring was not correct. Substring takes a starting position and then a number of characters from the starting position, not a starting position then an ending position. As such to get a date that starts at position 32 and is 8 characters long, you should use .substring(32,8), not .substring(32,39)

$FileLocation = "D:\Files"

Get-ChildItem $FileLocation | 
Where-Object {$ -match "File[123]\.txt\..*"} |
ForEach-Object {
    Switch ($[4]) {
        1 {$Date = Get-Content -Path $input.FullName -TotalCount 1 | ForEach-Object { $_.Substring(32,8) } }
        2 {$Date = Get-Content -Path $input.FullName -TotalCount 1 | ForEach-Object { $_.Substring(43,8) } }
        3 {$Date = Get-Content -Path $input.FullName -TotalCount 1 | ForEach-Object { $_.Substring(31,8) } }
    [PSCustomObject]@{'Was' = $($_.Name); 'Now' = $($_.Name -replace "\.\w*$", ".$Date")}
    Rename-Item -Path $_.FullName -NewName $($_.Name -replace "\.\w*$", ".$Date")


Was                        Now               
---                        ---               
File2.txt.2546367          File2.txt.20151014
File3.txt.asdgfq4er4yw4589 File3.txt.20150123
File1.txt.sadlkfjasdf      File1.txt.20140923

Ah so you can put your regex in the quotations. I did not know that would work. When I tried that the text in the brackets turned green like I was casting something so I gave up.

Also, you were using the -like operator. It does not use regex. -match does.

Hah that makes sense you wouldn’t say like this pattern… Match this pattern. I wish you sat next to me at work I would pick your brain all day.

or -notmatch this pattern. You got it.