Powershell Path Replacement - string

Hey it's me again with my paths :D
I write my Paths into a TXT-File.
Ex:
C:\Ex\am\ple\path.txt
C:\Ex\am\ple\file.txt
C:\Ex\am\ple\text.txt
Now I want to replace the "*.txt" at the end of every Path.
I tried the following:
(Get-Content ".\MYPATHS.txt") | Foreach-Object {$_ -replace "\*.txt"}| Set-Content ".\MYPATHS.txt"
Where's is my fault?

k, if you need just the path(without the files):
'C:\Ex\am\ple\path.txt', 'C:\Ex\am\ple\file.txt' | Split-Path -Parent
the list above
'C:\Ex\am\ple\path.txt', 'C:\Ex\am\ple\file.txt'
replaces 'Get-Content'. Output:
C:\Ex\am\ple
C:\Ex\am\ple

Related

How can I replace a string in multiple files with a value from a list, sequentially in Powershell?

Lets say I have a bunch of text files with people's names, that all have this as the content:
number
I want to replace "number" with a value from a CSV or text file, sequentially, and based on the file name. CSV has two columns, name and number:
Joe 5551011000
Gary 5551011001
Clark 5551011002
So I want to find the text file named Joe, and replace the "number" with "5551011000", and the text file named Gary, and replace "number" with "5551011001".
Thank you!
I didn't get too far:
Get-ChildItem "C:\test\*.txt" -Recurse | ForEach-Object -Process {
(Get-Content $_) -Replace 'changeme', 'MyValue' | Set-Content $_
}
This gets me party there, but I don't know how to find a specific file, then replace "number" in that file with the correct value that matches the name.
I also tried a different approach, with manual entry, and it works, but I need it to just be automated:
get-childitem c:\Marriott -recurse -include *.txt |
select -expand fullname |
foreach {
$new = Read-Host 'What is the new value you want for ' $_
(Get-Content $_) -replace 'number',$new |
Set-Content $_
}
I would convert your CSV to a hashtable, then this gets pretty simple.
$ReplaceHT = #{}
Import-Csv c:\path\to\file.csv -Delimiter ' ' -Header 'FileName','Number' | ForEach-Object {$ReplaceHT.add($_.FileName,$_.Number)}
Get-ChildItem c:\Marriott -recurse -include *.txt -PipelineVariable 'File'|Where{$_.name -in $ReplaceHT.Keys} |ForEach-Object{
(Get-Content $File.FullName) -replace 'changeme', $ReplaceHT[$File.Name] | Set-Content $File.FullName
}

How can I remove characters from a line in a text file without renaming the file?

I want to be able to take a file in a folder and write it to a text file in batch or PowerShell. The output in the text file should have FileName, NewFileName, DateModified. The FileName is what the file was named before it was ingested in a program and output. NewFileName is the name of the file that was output from the program and stored in the output folder.
The PowerShell script below is what I have used to get the name and date modified of the files to display in a text file.
Get-ChildItem -Path D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Audio\ -Recurse |
Select-Object #{n='File'; e={$_.Name + "," + $_.LastWriteTime}} |
Out-File "D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Audio\Log.txt"
Get-ChildItem -Path D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Video\ -Recurse |
Select-Object #{n='File'; e={$_.Name + "," + $_.LastWriteTime}} |
Out-File "D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Video\Log.txt"
However, the output I want is the original file name that was ingested.
FileName before ingested in program: Some_Name_file.mxf
NewFileName after ingested: random_exactly_37_characters_FileName.mxf_random_exactly_11_characters
The original file does not exist anymore, so I could have just added the path of that and said to write its name. So is there a way I can remove those 37 characters before the file name and the last 11 characters at the end of the filename and write that down on the same text file. I do not want to rename the NewFileName because it would change the date modified parameters.
This assumes that the underscores and the file extension are included in what you want to remove, and you always want to remove 37 leading characters and 11 following characters. You can do this using the Substring property of your file name.
$audioFiles = Get-ChildItem -Path D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Audio\ -File -Recurse |
Select-Object #{n='File';e={$_.Name.Substring(37,($_.Name.Length-37-11))}},LastWriteTime
$audioFiles | Export-Csv "D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Audio\Log.csv" -NoTypeInformation
$videoFiles = Get-ChildItem -Path D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Video\ -File -Recurse |
Select-Object #{n='File';e={$_.Name.Substring(37,($_.Name.Length-37-11))}},LastWriteTime
$videoFiles | Export-Csv "D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Video\Log.csv" -NoTypeInformation
Keep in mind that substring character indexes start at 0 and end at Length-1.
An alternative is to use the -replace operator, which uses regex for string matching.
$audioFiles = Get-ChildItem -Path D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Audio\ -File -Recurse |
Select-Object #{n='File';e={$_.Name -replace '^.{37}(.*).{11}$','$1'}},LastWriteTime
$audioFiles | Export-Csv "D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Audio\Log.csv" -NoTypeInformation
$videoFiles = Get-ChildItem -Path D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Video\ -File -Recurse |
Select-Object #{n='File';e={$_.Name -replace '^.{37}(.*).{11}$','$1'}},LastWriteTime
$videoFiles | Export-Csv "D:\Documents\Projects\Trans-Wrapping\TestOut\NewFiles\Video\Log.csv" -NoTypeInformation
The . matches any non-newline character.
{N} matches the previous mechanism (. in this case) N times.
(.*) is a capture group ($1) that matches any character until there are exactly 11 characters left.
^ denotes the beginning of the string.
$ denotes the end of string.
Essentially, the entire filename gets replaced with just the middle substring.

Partial string match and folder creation using PowerShell

I have a directory with thousands of files, and I would like to create new directories based on part of the file name, and then sort the partial matching files into those directories.
The files all start with the same prefix, "123-", and then have numbers random and ranging in length, but I do not want whatever is after the numbers. I tried regular expressions, but I am having issues with matching the varying number lengths after the "123-" and skipping everything after the middle number.
Example files:
directory\123-4441Zebra.pdf
directory\123-4441Tango.pdf
directory\123-768987Beta.pdf
directory\123-768987Tango.pdf
directory\123-34263XYP.pdf
Example Result:
directory\123-4441\123-4441Zebra.pdf
directory\123-4441\123-4441Tango.pdf
directory\123-768987\123-768987Beta.pdf
directory\123-768987\123-768987Tango.pdf
directory\123-34263\123-34263XYP.pdf
Try this:
$yourdir="C:\temp\root"
gci $yourdir -File -Filter 123-*.pdf | %{$newdir=$yourdir + "\" + ($_.Name -replace '(123-\d+).*', '$1'); New-Item -Path $newdir -Force -ItemType Directory; Move-Item -Path $_.FullName -Dest $newdir -Force }
PS C:\> '123-4441Zebra.pdf' -replace '(123-\d+).*', '$1'
123-4441
e.g.
gci "c:\place\" | mv -Dest { "c:\out\$($_.Name -replace '(123-\d+).*', '$1')\" } -Force -WhatIf
Auto-generated PS help links from my codeblock (if available):
gci is an alias for Get-ChildItem (in module Microsoft.PowerShell.Management)
mv is an alias for Move-Item (in module Microsoft.PowerShell.Management)

How to search a string in multiple files and return the names of files in Powershell?

I have started learning powershell a couple of days ago, and I couldn't find anything on google that does what I need so please bear with my question.
I have been asked to replace some text strings into multiple files. I do not necessarily know the extension of the possible target files and I don't know their location either. So far I have managed to recursively browse into the directory (get-ChildItem -recurse) and find the string I was looking for with get-content and select-string:
Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy"
The problem is, I can see the occurences of the text I am looking for, but I don't know how to tell PS to return the path and the name for every matching files as well.
How can I get the name and location of the files that contains the expression I am looking for?
This should give the location of the files that contain your pattern:
Get-ChildItem -Recurse | Select-String "dummy" -List | Select Path
There are a variety of accurate answers here, but here is the most concise code for several different variations. For each variation, the top line shows the full syntax and the bottom shows terse syntax.
Item (2) is a more concise form of the answers from Jon Z and manojlds, while item (1) is equivalent to the answers from vikas368 and buygrush.
List FileInfo objects for all files containing pattern:
Get-ChildItem -Recurse filespec | Where-Object { Select-String pattern $_ -Quiet }
ls -r filespec | ? { sls pattern $_ -q }
List file names for all files containing pattern:
Get-ChildItem -Recurse filespec | Select-String pattern | Select-Object -Unique Path
ls -r filespec | sls pattern | select -u Path
List FileInfo objects for all files not containing pattern:
Get-ChildItem -Recurse filespec | Where-Object { !(Select-String pattern $_ -Quiet) }
ls -r filespec | ? { !(sls pattern $_ -q) }
List file names for all files not containing pattern:
(Get-ChildItem -Recurse filespec | Where-Object { !(Select-String pattern $_ -Quiet) }).FullName
(ls -r filespec | ? { !(sls pattern $_ -q) }).FullName
This is how I would do it, you don't need get-content:
ls -r | Select-String dummy | select line,path
or
ls -r | Select-String dummy | fl *
To see what the different properties are...
This is faster. The second argument is -filter:
ls -r . *.bat | select-string netsh
ls -r -path . -filter *.bat | select-string netsh
This will display the path, filename and the content line it found that matched the pattern.
Get-ChildItem -Path d:\applications\*config -recurse | Select-String -Pattern "dummy"
Pipe the content of your
Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy"
to fl *
You will see that the path is already being returned as a property of the objects.
IF you want just the path, use select path or select -unique path to remove duplicates:
Get-ChildItem -recurse | Get-Content | Select-String -pattern "dummy" | select -unique path
I modified one of the answers above to give me a bit more information. This spared me a second query later on. It was something like this:
Get-ChildItem `
-Path "C:\data\path" -Filter "Example*.dat" -recurse | `
Select-String -pattern "dummy" | `
Select-Object -Property Path,LineNumber,Line | `
Export-CSV "C:\ResultFile.csv"
I can specify the path and file wildcards with this structures, and it saves the filename, line number and relevant line to an output file.
Get-ChildItem -r | ? {$_.psiscontainer -eq $false} | ? {gc $_.pspath |select-string -pattern "dummy"}
This will give you the full details of all files
To keep the complete file details in resulting array you could use a slight modification of the answer posted by vikas368 (which didn't seem to work well with the ISE autocomplete):
Get-ChildItem -Recurse | Where-Object { $_ | Select-String -Pattern "dummy" }
or in short:
ls -r | ?{ $_ | Select-String -Pattern "dummy" }
If you search into one directory, you can do it:
select-string -Path "c:\temp\*.*" -Pattern "result" -List | select Path
This will display a list of the full path to each file that contains the search string:
foreach ($file in Get-ChildItem | Select-String -pattern "dummy" | Select-Object -Unique path) {$file.path}
Note that it doesn't display a header above the results and doesn't display the lines of text containing the search string. All it tells you is where you can find the files that contain the string.
With PowerShell, go to the path where your files are and then type this command and replace ENTER THE STRING YOU SEARCH HERE (but keep the double quotes):
findstr /S /I /M /C:"ENTER THE STRING YOU SEARCH HERE" *.*
Have a nice day 🙂
This Scrit worked to find a specific file in a 3 000 000
Param
(
#Define o parametro do ano a eliminar "2020"
$DateDel = '2019',
#Define o parametro do registro do ficheiro "_800" ou "_800sm" ou "_200"
$ResFile1 = '_200',
$ResFile2 = '_800',
$ResFile3 = '_800sm',
#Define o parametro da terminacao do ficheiro "_800.jpg" ou "_800sm.jpg" ou "_200.jpg"
$TypeFile = '.jpg',
#Define o parametro de onde se localizado ficheiro "C:\users\Luis.Cunha\Desktop\LuisCunha\TarefaScript\TesteFinal\TesteScript1"
$HomePath = 'C:\Users\Luis.Cunha\Desktop\LuisCunha\TarefaScript'
)
#Inicia transcriçao de toda informação para o ficheiro .log indicado
Start-Transcript -Path $HomePath\CountDelItems.log -NoClobber -Append
Get-ChildItem $HomePath -Recurse -File | Measure-Object | %{$_.Count}
#o Get vai buscar o ficheiro com a data e a terminacao definidas no $homepath e $tipofich atraves do caminho indicado no $path
#depois confirma os valores que foram removidos com o verbose
Get-Childitem -Path $HomePath -Recurse -force | Where-Object { !$_.PSIsContainer -and $_.name -like "????$DateDel*$ResFile1$TypeFile" } | Measure-Object | %{$_.Count}
#Get-Childitem -Path $HomePath -Recurse -force | Where-Object { !$_.PSIsContainer -and $_.name -like "????$DateDel*$ResFile1$TypeFile" } | Remove-Item -Verbose -Force
Get-ChildItem $HomePath -Recurse -File | Measure-Object | %{$_.Count}
#Termina transcrição
Stop-Transcript

Renaming many folders in PowerShell

I have over 1000+ files that have to be renamed.
The first set folder and/or files are grouped by location, so the first four characters are the same for each file; there are four-five different locations. I need to delete the first few characters of the folder's name.
Example:
Old File: ABC_Doe, Jane
New File: Doe, Jane
any suggestions as to the quickest way to carry this out?
I've tried all of the following:
1st Attempt
$a = Get-ChildItem C:\example
$b = Where-Object {$_.name -like “*ABC_*”}
$cmdlet_name = “Rename-Item”
$d = (cmdlet_name $a $b)
invoke-expression $d
2nd Attempt
$e = Get-ChildItem C:\example
$f = $e.TrimStart (“ABC_”)
3rd Attempt
Rename-Item -{$_.name -like “*ASD*”, “”}
Try this, get all child items (files only), remove abc_ by replacing them (with nothing) and rename each file. To rename files in sub-directories add the -Recurse switch to the Get-ChildItem command:
Get-ChildItem c:\example -Filter ABC_* | Where-Object {!$_.PSIsContainer} | Rename-Item -NewName { ($_.BaseName -replace '^ABC_') + $_.Extension }
UPDATE
Actually, this should work as well and is much shorter (no need to append the file extension cause renaming is performed on the file name).
Get-ChildItem c:\example -Filter ABC_* | Where-Object {!$_.PSIsContainer} | Rename-Item -NewName { $_.Name -replace '^ABC_' }
get-childItem ABC_* | rename-item -newname { $_.name -replace 'ABC_','' }
Source: get-help rename-item -full

Resources