Creating folders and moving files in powershell - powershell

I have a folder with thousands of files (let's say .txt) with different names:
VBH_V001.txt
VDD_V001.txt
DTG_V001.txt
ADC_V001.txt
DFD_V001.txt
etc....
I need to create directories in that folder with the name of each file and then move those files to directories. The result should be for example Folder with the the name VBH (without _V001.txt) and in that folder I should have VBH_V001.txt file. How can I do that. Please advise.

cd <path to your folder>
$files = Get-ChildItem -file;
ForEach ($file in $files)
{
$folder = New-Item -type directory -name $file.BaseName;
Move-Item $file.FullName $folder.FullName;
}
This script creates a directory for each file and moves the file to this directory. To exclude _V001 from the directory name, you can call the TrimEnd method on $file.BaseName -
$file.BaseName.TrimEnd ("_V001")
Step by step.
First of all, go to the directory that contains your files.
Get a list of objects that represent your files by using the Get-ChildItem cmdlet with the -file attribute. These objects contain properties - such as BaseName, FullName, and so on.
Save this list to the $files variable.
Loop through the list with ForEach.
In the ForEach body, create a directory for each file with the New-Item cmdlet. The -type attribute specifies the type for the new item (-type directory), for the -name attribute substitute the $file.BaseName property. BaseName property returns a string with the name of the file without the extension and path.
Save the object of the newly created directory into the $folder variable.
Move the file using the Move-Item cmdlet. This cmdlet requires two attributes: source path and destination path. As the source path, use the FullName property of the file object, and the FullName property of the directory object for the destination path. FullName property returns the name of the file or directory that contains the full path, for example D:\directory\file.txt for a file and D:\directory\anotherDirectory for a directory.
It's not a big deal, actually, and without shortcuts it looks like a plain English.

What you basically need to do, is to:
Get a list of files in a selected folder through PowerShell.
Create new folders in a loop by
using the New-Item cmdlet which have name made by using substring of a name of a selected file.
For each of the files, move the file to the new location, using the Move-Item cmdlet.
Hope that helps.

Related

Remove everything before \

I need to copy a lot of files and use the same sort of folder structure where the files needs to go.
So for instance if I have the following two documents:
\\Server1\Projects\OldProject\English\Text_EN.docx
\\Server1\Projects\OldProject\English\Danish\Text_DA.docx
I would need to move them to a new place on the server, but they need to be in the same "language folder". So I need to move them like this:
\\Server1\Projects\OldProject\English\Text_EN.docx -> \\Server1\Projects\NewProject\English\Text_EN.docx
\\Server1\Projects\OldProject\English\Danish\Text_DA.docx -> \\Server1\Projects\NewProject\English\Danish\Text_DA.docx
The issue here is, that I would need to take names of the "language" folder and create them in the NewProject folder.
How would I be able to take and remove everything before the \, so I end up with only having the "language" folders like English\ and English\Danish
If the goal it to just replace the 'OldProject' folder with 'NewProject' in the file path you could use replace to make the change to the file path:
$filePath = Get-ChildItem \\Server1\Projects\OldProject\English\Text_EN.docx
Copy-Item $filePath.FullName -Destination ($filepath.FullName -replace "\bOldProject\b", "NewProject")
The '\b' is used to do a regex EXACT match for anything inside the tags.
Try the following, which, for each input file:
constructs the target dir. path by replacing the old project dir.'s root path with the new one's, thereby effectively replicating the old dir.'s subdirectory structure.
makes sure that the target dir. exists
then copies the input file to the target dir.
$oldProjectRoot = '\\Server1\Projects\OldProject'
$newProjectRoot = '\\Server1\Projects\NewProject'
Get-ChildItem -Recurse -Filter *.docx -LiteralPath $oldProjectRoot |
ForEach-Object {
# Construct the target dir. path, with the same relative path
# as the input dir. path relative to the old project root.
$targetDir =
$newProjectRoot + $_.Directory.FullName.Substring($oldProjectRoot.Length)
# Create the target dir., if necessary (-Force returns any preexisting dir.)
$null = New-Item -Force -Type Directory $targetDir
$_ # Pass the input file through.
} |
Copy-Item -Destination { $targetDir } -WhatIf
Note: The -WhatIf common parameter in the command above previews the operation. Remove -WhatIf once you're sure the operation will do what you want.

Copying a folder with contents without knowing the full path to the folder to another folder

Is this possible using powershell or cmd? I only know the possibility to copy folder knowing the full path to the folder to be copied.
We assume that I want to copy to C:\copy the examp1, examp2, examp3 folders from the path
for examp1 C:\Users\Downloads\path1
for examp2 C:\Users\Downloads\path2
for examp3 C:\Users\Downloads\path3
but I don't know the exact name in place of the path1 and so on.
edit:
in general, all the folders that are to be copied (examp1,examp2,examp3 and so on) have a path which is
C:\Users\Downloads\2020random\examp1
C:\Users\Downloads\2021random\examp2
and so on.
but there are also folders in the
C:\Users\Downloads
which I don't want to copy and which also have a path, for example
C:\Users\Downloads\202020random\exampnottocopy.
to sum up, I have a path:
C:\Users\Downloads
which in turn contains various folders that may start with
2020random
2020random
.
.
.
2021random
2021random
and in turn they contain the folders I want to copy - I have a complete list of folders I want to copy.
and it is for example:
C:\Users\Downloads\2020random\examp1
C:\Users\Downloads\2021random\examp2
C:\Users\Downloads\2021random\examp3
and so on.
The difficulty is that not every folder in the location
C:\Users\Downloads\2020random
.
.
.
C:\Users\Downloads\2021random
contains a folder that is in my list - so I don't want to copy everything that is in the location I am copying from and that the full path to the copied folders is not known.
Assuming that you have your folders you'd like to copy in a textfile, you can try this.
Load the content of your textfile into the variable $foldersyouwant
$foldersyouwant = Get-Content -Path "yourPath"
Then you can simply output that data by using this command here
Get-ChildItem -Path C:\Users\Downloads\ -Recurse | Where-Object {$_.Name -in $foldersyouwant}
Does it show your expected folders?
Yes, then you can add another pipe and do the magic
Get-ChildItem -Path C:\Users\Downloads\ -Recurse | Where-Object {$_.Name -in $foldersyouwant} | Copy-Item -Destination "yourDestination"

Copy files in a directory, to folders with same name as file

I have multiple files that I want to copy each file to a folder with same name
For example, the files
orange_file100 , orange_file200 , orange_file300 , apple_file120 , apple_file150
I want to move each file to a folder that contain part of the filename say orange and apple so the result will be
orange\orange_file100
orange\orange_file200
orange\orange_file300
apple\apple_file120
apple\apple_file150
How can I do that through powershell, should I use Get-ChildItem then ForEach{Copy-Item) ?
You can use Get-Childitem with a -File or -Directory to only grab the files or folders in a folder, that way you wont grab a folder and try place it in itself.
For example, the code below will only grab the files in the current directory
Get-Childitem -File
You can then use some regex to split the names so you can get the fruit name e.g.
$String.split('_')[0]
You should insert it into a list or array or something to store it, but now you have a list of files and fruit names.
Now you can loop over the list and start to move or copy the files into the right folder structure
Foreach($file in $FileList){
if($file.name -matches $Fruitname){
if($file.name -notmatch $pwd.path ){
mkdir $file.name
cd $file.name
move-item $file.fullname $pwd
}
}
}
The code above is just a quick attempt. It probably wont work the first time and you should make adjustments to understand what you are doing.
A few notes
$pwd gets the current directory. I'm assuming Get-Childitem returns the list of files in the correct order, so you will get Orange_100, then Orange_200 and so on
Get-Childitem returns a powershell object. The file names can be accessed using $_.name or the full path using $_.fullname
If -matches doesn't work, you can also try -like or -in
I didn't add in the first fruit folder into the code above, but it won't be hard to create
Remember to play around and find whats best for you.

Powershell , remove folder with the same name like .zip

I must delete files which have been extracted from a zip file, into a folder named after the zip file, i.e.:
\test1.zip -> \test1
My script must find the folder which have the same name as the zip file and delete this folder.
Get a list of all of the Zip files in the directory, then loop over the results and delete any folder with the same name minus the extension, also known as the BaseName.
Get-ChildItem -Filter *.zip | `
ForEach-Object { if (Test-Path $_.BaseName) {
Remove-Item -Recurse -Force $_.BaseName }
}
You can enter the entire command on one line, I have split it up so that it is easy to read on here. I used the following commands in this example:
Get-ChildItem - Creates a object in the pipeline for each file with a .zip extension
ForEach-Object - Simply allows you to perform an action for each object in the pipeline.
Remove-Item - note the use of -Recurse and -Force ensures that the folder is removed even if it contains files, you will not be asked to confirm.

PowerShell - Rename file to the name of the folder in which it is located

I don't know if this would be best done in PowerShell, but basically I have a lot of movies with names that are incorrect. The folder name for each movie is correct however.
Within a folder, I want to go through each folder and rename an .mp4 file to the same name as the folder.
Each folder has only an .mp4 file in it and a .jpg file, but I want to rename just the .mp4 file (although renaming both really wouldn't be bad either.)
Is there a simple way to do this in PowerShell?
A readable version:
Get-ChildItem -Attributes Directory D:\Videos | ForEach-Object {
Get-ChildItem -Path $_ *.mp4 | Rename-Item -NewName "$_.mp4"
}
The first Get-ChildItem gets all the directory objects within D:\Videos and ForEach-Object iterates over each of those directories as $_ in the following block.
Inside the block, Get-ChildItem is used again to get an mp4 file from the given directory via the -Path option. Finally, Rename-Item is used to rename the video file without moving it from its current directory.
Something like this should work:
# run from your D:\Movies (or whatever) folder
# Go through all subfolders of the folder we're currently in, and find all of the .MP4
# files. For each .MP4 file we find...
ls -Recurse -Filter *.mp4 | %{
# Get the full path to the MP4 file; use it to find the name of the parent folder.
# $_ represents the .MP4 file that we're currently working on.
# Split-Path with the -Parent switch will give us the full path to the parent
# folder. Cast that path to a System.IO.DirectoryInfo object, and get the
# Name property, which is just the name of the folder.
# There are other (maybe better) ways to do this, this is just the way I chose.
$name = ([IO.DirectoryInfo](Split-Path $_.FullName -Parent)).Name
# Tell the user what we're doing...
Write-Host "Renaming $_ to $($name).mp4..."
# Rename the file.
# We have to provide the full path to the file we're renaming, so we use
# $_.FullName to get it. The new name of the file is the same as that of the
# parent folder, which we stored in $name.
# We also remember to add the .MP4 file extension back to the name.
Rename-Item -Path $_.FullName -NewName "$($name).mp4"
}
Here's a cross version example:
Get-ChildItem D:\temp\*\*.mp4 | Rename-Item -NewName {$_.Directory.Name +'.mp4'}