Author Posts

November 30, 2015 at 11:30 am

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.

Thanks!!

November 30, 2015 at 11:34 am

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

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

$var2[0]

November 30, 2015 at 11:45 am

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
$var.Substring(5,15)

November 30, 2015 at 11:48 am

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

November 30, 2015 at 11:48 am

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.

November 30, 2015 at 11:49 am

Tag, you're it 🙂

November 30, 2015 at 11:53 am

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)
$var2

November 30, 2015 at 11:53 am

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.

November 30, 2015 at 11:54 am

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.

November 30, 2015 at 1:09 pm

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!!!!!

November 30, 2015 at 1:55 pm

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

November 30, 2015 at 2:00 pm

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

November 30, 2015 at 2:21 pm

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.

November 30, 2015 at 9:02 pm

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

Thanks a bunch!!

December 1, 2015 at 1:07 pm

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
(File)[1-3](\.txt)

$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")
}

December 1, 2015 at 5:13 pm

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 {$_.name -match "File[123]\.txt\..*"} |
ForEach-Object {
    Switch ($_.name[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")
}

Results:

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

December 1, 2015 at 5:24 pm

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.

December 1, 2015 at 5:34 pm

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

December 1, 2015 at 5:39 pm

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.

December 1, 2015 at 5:42 pm

or -notmatch this pattern. You got it.

December 2, 2015 at 6:53 am

This looks great.
Thanks!!!

One quick question.
the 3 files I am dealing with have a little different naming convention. Sorry I was a little too genaric on my sample script.
The 3 files are more like
FileP.txt.1234567
FileD.txt.1234567
FileR.txt.1234567

So this is how I am thinking to update the script

Get-ChildItem $FileLocation | 
Where-Object {$_.name -match "File[PDR]\.txt\..*"} |
ForEach-Object {
    Switch ($_.name[4]) {
        P {$Date = Get-Content -Path $input.FullName -TotalCount 1 | ForEach-Object { $_.Substring(32,8) } }
        D {$Date = Get-Content -Path $input.FullName -TotalCount 1 | ForEach-Object { $_.Substring(43,8) } }
        R {$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")
}

December 2, 2015 at 6:59 am

That looks good. You can also remove the [pscustomobject] line if you like. I just put it there to see some output in the console whil testing.

December 2, 2015 at 7:35 am

Getting this error when I run the script

Get-Content : Cannot bind argument to parameter 'Path' because it is null.

Thanks!!

December 2, 2015 at 7:57 am

looks like it did not find matches based on the path and or file names check the path variable and the file names to insure the regex is looking for the right file

December 2, 2015 at 9:57 am

Here is my code but still getting the error.

$FileLocation = "D:\Files"

Get-ChildItem $FileLocation | 
Where-Object {$_.name -match "File[PDR]\.txt\..*"} |
ForEach-Object {
    Switch -regex ($_.name[4]) {
        "P" {$Date = Get-Content -Path $input.FullName -TotalCount 1 | ForEach-Object { $_.Substring(32,8) } }
        "D" {$Date = Get-Content -Path $input.FullName -TotalCount 1 | ForEach-Object { $_.Substring(43,8) } }
        "R" {$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")
}

December 2, 2015 at 10:32 am

It appears you may be running an out dated version of PowerShell. The code works perfectly for me in PoSh 3.0 and 4.0, but gives your error in 2.0. You should upgrade.

December 2, 2015 at 10:43 am

Ahh. If upgrading where only an option 😉

December 2, 2015 at 10:54 am

Ok then, here is a workaround that is PoSh 2.0 compatible.

$FileLocation = "D:\Files"

Get-ChildItem $FileLocation | 
Where-Object {$_.name -match "File[PDR]\.txt\..*"} |
ForEach-Object {
    $input = $_
    Switch -regex ($_.name[4]) {
        "P" {$Date = Get-Content -Path $input.FullName -TotalCount 1 | ForEach-Object { $_.Substring(32,8) } }
        "D" {$Date = Get-Content -Path $input.FullName -TotalCount 1 | ForEach-Object { $_.Substring(43,8) } }
        "R" {$Date = Get-Content -Path $input.FullName -TotalCount 1 | ForEach-Object { $_.Substring(31,8) } }
    }
    New-Object -Type PSObject -Property @{'Was' = $($_.Name); 'Now' = $($_.Name -replace "\.\w*$", ".$Date")}
    Rename-Item -Path $_.FullName -NewName $($_.Name -replace "\.\w*$", ".$Date")
}

December 2, 2015 at 2:16 pm

This is really close.
It is working for the FileD but it is using the same bit of code for the other 2 files.

Any suggestions?

Thanks!!!

December 2, 2015 at 2:29 pm

The switch is looking at the 5th character in the file names could it be a case issue? Unless the $date variable is no being set after the first pass.

Clear the $date variable after the foreach

ForEach-Object {
$date = $null

If it still sets the date the same then it is selecting switch D for each pass

December 2, 2015 at 6:23 pm

Cam, you should start a separate post.

December 2, 2015 at 6:24 pm

Nathan, can you give some actual examples of the 3 file names and the first line of each file?

December 3, 2015 at 5:52 am

Due to the project I am working on I can't give exact names of these files but I can say the each file has the same number of charters.
XXXXXXXP.txt.12345678912345678
XXXXXXXD.txt.12345678912345678
XXXXXXXR.txt.12345678912345678

Thanks so much for the help. The Powershell Community is one of the best there is 🙂

December 3, 2015 at 6:45 am

is the XXXXXXX the same name for all files how many characters is the XXXXXXX

December 3, 2015 at 7:11 am

It is the same. Each X represents one of the characters of the file name.
The P, D and R are the non common characters and the charaters following the txt. are a time stemp for when the fire was created.

Thanks

December 3, 2015 at 7:15 am

the 4 in his Switch is looking at the PDR in your file 5th character if your actual file has seven characters before the PDR you need to change the number to 7. Chances are your 5th character in all your file names is a D and that is why it is selecting that switch for every file

$FileLocation = "D:\Files"

Get-ChildItem $FileLocation | 
Where-Object {$_.name -match "File[PDR]\.txt\..*"} |
ForEach-Object {
    $input = $_
    Switch -regex ($_.name[7]) {
        "P" {$Date = Get-Content -Path $input.FullName -TotalCount 1 | ForEach-Object { $_.Substring(32,8) } }
        "D" {$Date = Get-Content -Path $input.FullName -TotalCount 1 | ForEach-Object { $_.Substring(43,8) } }
        "R" {$Date = Get-Content -Path $input.FullName -TotalCount 1 | ForEach-Object { $_.Substring(31,8) } }
    }
    New-Object -Type PSObject -Property @{'Was' = $($_.Name); 'Now' = $($_.Name -replace "\.\w*$", ".$Date")}
    Rename-Item -Path $_.FullName -NewName $($_.Name -replace "\.\w*$", ".$Date")
}

December 3, 2015 at 7:40 am

Perfection!!!!!

THANKS!!!!!!!!!