Say I have following file structure
L:\Enterprise\Legal\Planning\Contacts\A-D\
Under A-D I have 50 Folders which is named after company name. So it looks like this
L:\Enterprise\Legal\Planning\Contacts\A-D\3-M Company\subfolder\sub-subfolder\files.txt
L:\Enterprise\Legal\Planning\Contacts\A-D\ABC Company\subfolder\sub-subfolder\files.txt
L:\Enterprise\Legal\Planning\Contacts\A-D\XYZ Company\subfolder\sub-subfolder\files.txt
L:\Enterprise\Legal\Planning\Contacts\A-D\AAA Company\subfolder\sub-subfolder\files.txt
Is there a way to get the company name from the above file structure using powershell or some windows script?
if your goal is to have a list of company name one way is:
cd L:\Enterprise\Legal\Planning\Contacts\A-D\
dir | select -expand fullname | % { ($_ -split '\\')[6] }
Some people may also find that this works instead
dir | select -expand fullname | % { ($_ -split '\\')[7] }
If you are importing a list of files/folders from a CSV, you could do this:
$strings = Import-CSV -Path "C:\PathToCSV.csv"
foreach ($string in $strings) {
$string -replace 'L:\\Enterprise\\Legal\\Planning\\Contacts\\A-D\\' -replace '\\subfolder\\sub-subfolder\\files.txt'
}
Note the double-slashes (\\). You have to escape the slashes, otherwise they are treated as special. Output should look like:
3-M Company
ABC Company
XYZ Company
AAA Company
Related
I'm trying to get the output of two separate files although I'm stuck on the wild card or contains select-string search from file A (Names) in file B (name-rank).
The contents of file A is:
adam
george
william
assa
kate
mark
The contents of file B is:
12-march-2020,Mark-1
12-march-2020,Mark-2
12-march-2020,Mark-3
12-march-2020,william-4
12-march-2020,william-2
12-march-2020,william-7
12-march-2020,kate-54
12-march-2020,kate-12
12-march-2020,kate-44
And I need to match on every occurrence of the names after the '-' so my ordered output should look like this which is a combination of both files as the output:
mark
Mark-1
Mark-2
Mark-3
william
william-2
william-4
william-7
Kate
kate-12
kate-44
kate-54
So far I only have the following and I'd be grateful for any pointers or assistance please.
import-csv (c:\temp\names.csv) |
select-string -simplematch (import-csv c:\temp\names-rank.csv -header "Date", "RankedName" | select RankedName) |
set-content c:\temp\names-and-ranks.csv
I imagine the select-string isn't going to be enough and I need to write a loop instead.
The data you give in the example does not give you much to work with, and the desired output is not that intuitive, most of the time with Powershell you would like to combine the data in to a much richer output at the end.
But anyway, with what is given here and what you want, the code bellow will get what you need, I have left comments in the code for you
$pathDir='C:\Users\myUser\Downloads\trash'
$names="$pathDir\names.csv"
$namesRank="$pathDir\names-rank.csv"
$nameImport = Import-Csv -Path $names -Header names
$nameRankImport= Import-Csv -Path $namesRank -Header date,rankName
#create an empty array to collect the result
$list=#()
foreach($name in $nameImport){
#get all the match names
$match=$nameRankImport.RankName -like "$($name.names)*"
#add the name from the First list
$list+=($name.names)
#if there are any matches, add them too
if($match){
$list+=$match
}
}
#Because its a one column string, Export-CSV will now show us what we want
$list | Set-Content -Path "$pathDir\names-and-ranks.csv" -Force
For this I would use a combination of Group-Object and Where-Object to first group all "RankedName" items by the name before the dash, then filter on those names to be part of the names we got from the 'names.csv' file and output the properties you need.
# read the names from the file as string array
$names = Get-Content -Path 'c:\temp\names.csv' # just a list of names, so really not a CSV
# import the CSV file and loop through
Import-Csv -Path 'c:\temp\names-rank.csv' -Header "Date", "RankedName" |
Group-Object { ($_.RankedName -split '-')[0] } | # group on the name before the dash in the 'RankedName' property
Where-Object { $_.Name -in $names } | # use only the groups that have a name that can be found in the $names array
ForEach-Object {
$_.Name # output the group name (which is one of the $names)
$_.Group.RankedName -join [environment]::NewLine # output the group's 'RankedName' property joined with a newline
} |
Set-Content -Path 'c:\temp\names-and-ranks.csv'
Output:
Mark
Mark-1
Mark-2
Mark-3
william
william-4
william-2
william-7
kate
kate-54
kate-12
kate-44
I'm looking to create an array of files (pdf's specifically) based on filenames in Powershell. All files are in the same directory. I've spent a couple of days looking and can't find anything that has examples of this or something that is close but could be changed. Here is my example of file names:
AR - HELLO.pdf
AF - HELLO.pdf
RT - HELLO.pdf
MH - HELLO.pdf
AR - WORLD.pdf
AF - WORLD.pdf
RT - WORLD.pdf
HT - WORLD.pdf
....
I would like to combine all files ending in 'HELLO' into an array and 'WORLD' into another array and so on.
I'm stuck pretty early on in the process as I'm brand new to creating scripts, but here is my sad start:
Get-ChildItem *.pdf
Where BaseName -match '(.*) - (\w+)'
Updated Info...
I do not know the name after the " - " so using regex is working.
My ultimate goal is to combine PDF's based on the matching text after the " - " in the filename and the most basic code for this is:
$file1 = "1 - HELLO.pdf"
$file2 = "2 - HELLO.PDF"
$mergedfile = "HELLO.PDF"
Merge-PDF -InputFile $file1, $file2 -OututFile $mergedfile
I have also gotten the Merge-PDF to work using this code which merges all PDF's in the directory:
$Files = Get-ChildItem *.pdf
$mergedfiles = "merged.pdf"
Merge-PDF -InputFile $Files -OutputFile $mergedfiles
Using this code from #Mathias the $suffix portion of the -OutputFile works but the -InputFile portion is returning an error "Exception calling "Close" with "0" argument(s)"
$groups = Get-ChildItem *.pdf |Group-Object {$_.BaseName -replace
'^.*\b(\w+)$','$1'} -AsHashTable
foreach($suffix in $groups.Keys) {Merge-PDF -InputFile $(#($groups[$suffix]))
-OutputFile "$suffix.pdf"}
For the -InputFile I've tried a lot of different varieties and I keep getting the "0" arguments error. The values in the Hashtable seem to be correct so I'm not sure why this isn't working.
Thanks
This should do the trick:
$HELLO = Get-ChildItem *HELLO.pdf |Select -Expand Name
$WORLD = Get-ChildItem *WORLD.pdf |Select -Expand Name
If you want to group file names by the last word in the base name and you don't know them up front, regex is indeed an option:
$groups = Get-ChildItem *.pdf |Group-Object {$_.BaseName -replace '^.*\b(\w+)$','$1'} -AsHashTable
And then you can do:
$groups['HELLO'].Name
for all the file names ending with the word HELLO, or, to iterate over all of them:
foreach($suffixGroup in $groups.GetEnumerator()){
Write-Host "There are $($suffixGroup.Value.Count) files ending in $($suffixGroup.Key)"
}
Another option is to get all items with Get-ChildItem and use Where-Object to filter.
$fileNames = Get-ChildItem | Select-Object -ExpandProperty FullName
#then filter
$fileNames | Where-Object {$_.EndsWith("HELLO.PDF")}
#or use the aliases if you want to do less typing:
$fileNames = gci | select -exp FullName
$fileNames | ? {$_.EndsWith("HELLO.PDF")}
Just wanted to show more options -especially the Where-Object cmdlet which comes in useful when you're calling cmdlets that don't have parameters to filter.
Side note:
You may be asking what -ExpandProperty does.
If you just call gci | select -exp FullName, you will get back an array of PSCustomObjects (each of them with one property called FullName).
This can be confusing for people who don't really see that the objects are typed as it is not visible just by looking at the PowerShell script.
In a directory there will be 2 type of files with same name but different extension for eg:1.png , 1.txt, test_76.png,test_76.txt, test_70.png. In this case test_70.png dosent have its .txt counterpart.I am using this code
$scL = dir *.txt | select Basename
$SList = #($scL -notmatch "MICRO")
$pList = dir *.png | select Basename
$PList = #($pList -notmatch "MICRO")
Compare-Object $PList $SList | ForEach-Object {$_.InputObject} | out-file result.txt
but i am unable to get the desired output that is test_70.png in the output file.Also i want to wrap the output inside the text file in double quotes i.e; the outfile should contain entry like this "test_70.png". Can anyone throw light on what am i missing in the compare-object cmdlet.
Your InputObject is a file object so you will need to access the name. Also in Powershell you can access the properties of the the items in a collection directly. Something like this:
(Compare-Object $PList $SList).InputObject.Name | % {"`"$_`""} | Out-File result.txt
I have 2 folders: 'Old' and 'New'. Most of the files from 'Old' have been copied to 'New'. However, the structure of the sub-folders in 'Old' and 'New" are different. So the file-path for a file in 'Old' is very different from its copy in 'New'.
I need to loop through each file in 'Old', search for that file in 'New', and write the old and new file-paths for each file to a text file.
I have been assigned to do this manually, but it will take a long time due to the number of files. So I want to write a script. I am new to Powershell and am having difficulty figuring out which cmdlets can help me with my task.
I will appreciate any kind of guidance. Thank you.
try Something like this
#list old files
$patholdfile="c:\temp"
$listoldfile=Get-ChildItem $patholdfile -File -Recurse | select Name, FullName
#list new files
$pathnewfile="c:\temp2"
$listnewfile=Get-ChildItem $pathnewfile -File -Recurse | select Name, FullName
#extract liste file old and name and search all file in newlist
$resultsearch=#()
foreach ($currentfile in $listoldfile)
{
$resultsearch+=New-Object psobject -Property #{
Name=$currentfile.Name
OldPath=$currentfile.FullName
#if you want the firt founded uncomment this and comment after
#NewPaths=($listnewfile | Where {$_.Name -eq $currentfile.Name} | select FullName -First 1).FullName
NewPaths=($listnewfile | Where {$_.Name -eq $currentfile.Name} | select FullName).FullName -join "~"
}
}
#export result in csv file
$resultsearch | select name, OldPath , NewPaths | export-csv -Path "c:\temp\result.txt" -NoTypeInformation
I need to import a csv, select a string and change some part of it's value to $env:username. I think I have to work with select-string to get the string, but i'm stuck with changing the value. Or is it possible to write $env:username directly into the csv? I wasn't able to do it. also, the CSV should stay the way it is, only the current powershell session needs the correct string
CSV looks like this, userhome should be replaced by $env:username:
Test Test2
----- -----
Hi C:\user\userhome
something C:\test\install
hello C:\windows
Thats what i tried but I'm not successfull.
$test.Test2 | sls userhome -replace ($env:username)
another approach:
sls ($test.Test2).value -replace ("userhome",$env:username)
EDIT: This is the whole command where this csv is needed - just for information:
$Drives = Import-CSV .\NetworkDrives.csv -Delimiter ';' | ? {(($_.Group).split(',') -contains $UserOU) -and (!(Test-Path $_.Letter))} | % { #Do Stuff }
I'm glad that PetSerAl's answer in the comments worked for you. Personally I think it may have been simpler to use Get-Content, run a -Replace on that, and then pipe to ConvertFrom-CSV instead of Import-CSV.
$Drives= (Get-Content .\NetworkDrives.csv) -Replace "userhome",$env:username | ConvertFrom-CSV -Delimiter ';' | ? {(($_.Group).split(',') -contains $UserOU) -and (!(Test-Path $_.Letter))} | % { #Do Stuff }