batch-script to replace dots in foldernames with spaces - batch-file

a user of mine is having problems with syncing cloud to local workstation. he is having lots of folders in a deep (10+) folder structure pattern and every folder is containing at least three dots ("xy.asdf.qwer $generic descriptor").
so now there is big foobar. online everything works fine, new files can be created and edited as expected. but the synced files keeps crashing on windows 10 enterprise and explorer warns with "bad foldername" and stuff. so i allowed long folder names (260 chars max.... seriously?) via GPO for user and i thought "well done. problem solved" ... but no... synced local files are still having trouble... so i allowed same option via regedit. same same. explorer keeps complaining.
so i decided to change folder names and remove the dots and replace them with spaces. so folder "xy.asdf.qwer $generic descriptor" will be "xy asdf qwer $generic descriptor". user says it's fine so i wrote a batch to rename folders. sry, my powershell is really bad. but if u know a solution in powershell it is appreciated and fine as well.
#echo off
setlocal enabledelayedexpansion
set "leer= "
set "punkt=."
call :rekursion
goto :eof
:rekursion
for /D %%d in (*) do (
set name=%%~nxd
ren "%%d" "!name:%punkt%=%leer%!"
cd %%d
call :rekursion
cd ..
)
exit /b
batch is working fine, but keeps throwing errors and telling me "not allowed" ... what is wrong with it? why is it working but complaining? what am i missing? all rights are set proper (full access...)
[sry for bad English...]

This PowerShell script will do what you want. If you are on a supported Windows platform, PowerShell will be available.
I would not want SPACE characters in directory or file names, but that is your choice. When you are satisfied that the names would be changed correctly, remove the -WhatIf from the Rename-Item command.
#Requires -Version 3
$BaseDir = 'C:\src\t'
Get-ChildItem -Recurse -Directory -Path $BaseDir |
Sort-Object -Descending -Property FullName |
Where-Object { $_.Name -match '\.' } |
ForEach-Object {
$NewName = $_.Name -replace '\.',' '
Rename-Item -Path $_.FullName -NewName $NewName -WhatIf
}

The order is the issue. You are renaming the folder BEFORE you try to change directories. It works because after you rename the folder, the loop will pick up the new folder name, but is much less efficient. I was seeing errors on the 'cd' line. This works for me and is a bit simpler:
#echo off
setlocal enabledelayedexpansion
set "leer= "
set "punkt=."
:rekursion
for /D %%d in (*) do (
pushd %%d
call :rekursion
popd
set name=%%~nxd
ren "%%d" "!name:%punkt%=%leer%!"
)

Related

Remove nef files that haven't got a corresponding jpg file in a folder

I would like to write a script that searches through a folder and deletes any raw files (.nef) that don't have a matching jpg. For example,
Folder structure:
DSC_0001.nef
DSC_0001.jpg
DSC_0002.nef
DSC_0003.nef
The program would delete DSC_0002.nef and DSC_0003.nef.
How can I do this?
FOR /R %%F IN (*.NEF) DO #IF NOT EXIST "%%~dpnF.jpg" DEL "%%F"
Note: the /R switch means recursive (i.e. it will continue to run this command throughout the entire directory tree from the directory where it is run from). Omit that switch if you don't want to process subdirectories as well.
A possible PowerShell solution:
Get-ChildItem -Path "C:\temp\nef" -Filter "*.nef" | foreach {
if( -not (Get-Item $_.FullName.Replace('.nef','.jpg') -ErrorAction SilentlyContinue)){
$_ | Remove-Item -WhatIf
}
}
Remove the -WhatIf to actually make it delete the files.
You will need to use (for a single folder):
#echo off
cd to\folder
for %%A IN (*.nef) do (
if not exist %%~nA.jpg (del %%~fA)
)
And for multiple folders, use:
#echo off
for /R "full_path_to_parent_folder" %%A IN (*.nef) do (
if not exist %%~dpnA.jpg (del %%~fA)
)

batch to delete subfolders of all subfolders

So i'm currently trying to delete a bunch of subfolders that were created by a program, on a recurring basis because it will recreate the subfolders. I know how to schedule the batch file, right now my issue is how to efficiently create the batch file to begin with. To clarify, say i have a directory named D:\IGSG. There are 250 folders within D:\IGSG, and within each one of those is a folder named D:\IGSG\F252341\arg. I want to delete all of the \arg folders, from all ~250 F folders I have, without deleting the other files inside the F folders. Right now the only way to do it that I know of would be to have a batch that goes
cd D:\IGSG\F252341
del /Q arg
and to repeat those lines for every subfolder, but typing out those folder names for every folder in there would be tedious, especially considering new ones are created from time to time. So i'm looking for a way with a batch to delete the subfolder of a subfolder, without deleting other files, if that makes sense.
On the cmd line for /d /r X:\path in combination with a wildcard will enumerate all folders names arg the appended .? meets this requirement:
for /d /r D:\IGSG %A in (arg.?) do #echo rd /s /q "%A"
if the output looks right remove the echo.
In a batch file double the %-signs -> %%A
#Echo off
for /d /r D:\IGSG %%A in (arg.?) do echo rd /s /q "%%A"
One of the rare cases where batch/cmd line can compete with PowerShell.
This PowerShell script will recurse through the subdirectory structure and delete all files and subdirectories inside arg directories. Be sure to change the location of the IGSG directory to yours. When you are satisfied that the correct files will be deleted, remove the -WhatIf from the Remove-Item cmdlet.
Get-ChildItem -Directory -Recurse -Path 'C:\src\t\delsubs\IGSG\F*' -Filter 'arg' |
Remove-Item -Path {(Join-Path -Path $_.FullName -ChildPath '*')} -Recurse -Force -WhatIf
If you need to run it from a cmd.exe shell, put the code above into a file named 'dodel.ps1' and run using:
powershell -NoProfile -File .\dodel.ps1

cmd how to delete JPG file and keep only RAW

I´m taking pictures with my mobile phone sometimes in JPG only, but sometimes in RAW. When shooting RAW, mobile phone actually stores two files (filename.jpg and filename.dng).
I would like to write a script which would search defined folder and delete all JPGs which have same filename like the DNGs (RAW).
Example - folder has following files:
IMG_20170625_105228.dng
IMG_20170625_105228.jpg
IMG_20170625_105326.jpg
IMG_20170625_105337.jpg
IMG_20170625_105350.dng
IMG_20170625_105350.jpg
Script should delete:
IMG_20170625_105228.jpg
IMG_20170625_105350.jpg
Iterate over the .dng files and if a like-named .jpg file exists, delete it. When you are satisfied that the correct files would be deleted, remove the ECHO from the DEL command.
PUSHD "C:\the\dir\containing\pics"
FOR /F "usebackq tokens=*" %%f IN (`DIR /B "*.dng"`) DO (
IF EXIST "%%~nf.jpg" (ECHO DEL "%%~nf.jpg")
)
POPD
If, for whatever reason, you wanted to do this in PowerShell, you could do something like this. When the correct files are being removed, remove the -WhatIf from the Remove-Item command. I would be interested to hear from anyone about a better way to do this in PowerShell.
$picdir = 'C:\dir\path\to\pics'
Get-ChildItem -Path $picdir -File -Filter '*.dng' |
Where-Object { Test-Path -Path "$($_.DirectoryName)/$($_.BaseName).jpg" -PathType Leaf } |
Select-Object #{Name="Path";Expression={"$($_.DirectoryName)\$($_.BaseName).jpg"}} |
Remove-Item -WhatIf

Move .txt files in different folders to a single folder using Batch file

I'm trying to move all .txt files in different folders to a single folder using a batch file, I'm new to batch coding so I'm having some difficulties.
My code is as follows:
FOR /D /r %%G IN ("C:\Users\Rodrigo\Desktop\PR\2016\08.2016\") DO MOVE G\*.txt C:\Users\Rodrigo\Desktop\PR\2016\
See the correct syntax of For /r or in an open cmd window type help for
#Echo off
For /r "C:\Users\Rodrigo\Desktop\PR\2016\08.2016\" %%G IN (*.txt
) Do echo Move "%%G" "C:\Users\Rodrigo\Desktop\PR\2016\"
Pause
If the output to screen looks OK remove the echo in front of the move command.
You could do this all in PowerShell. I am not sure it will work if you do not pass the $_.FullName which contains the path to the file.
Get-ChildItem -Path "C:\Users\Rodrigo\Desktop\PR\2016\08.2016\" -Filter *.txt | `
ForEach-Object { $_.FullName } | `
Move-Item -Destination "C:\Users\Rodrigo\Desktop\PR\2016\"

Script to move sub-sub-folders one level up (Batch or PowerShell)

I have found a few similar problems on Stackoverflow, and after trying out the solutions, my problem remains unsolved.
Here is my directory structure:
D:\XYZ\Adam Jay\Adam Jay\files.txt
D:\XYZ\Adam Jay\Adam Jay\SomeFolder\
D:\XYZ\Adam Jay\Adam Jay\OtherFolder\Some File.doc
D:\XYZ\Mary Poppins\Mary Poppins\myOtherFile.txt
and I have about 2000 of these.
My goal is to simply cut out the redundant sub-sub folder, following the above structure. Manually, I would simply cut the "sub-sub" folder "Adam Jay" and paste it into XYZ, where-in it will replace or merge with the upper-level "Adam Jay" (moving whatever files and folders with it).
The desired result:
D:\XYZ\Adam Jay\files.txt
D:\XYZ\Adam Jay\SomeFolder\
D:\XYZ\Adam Jay\OtherFolder\Some File.doc
D:\XYZ\Mary Poppins\myOtherFile.txt
I have very little knowledge of batch scripts, and no knowledge of PowerShell. By modifying a script I found here on StackOverflow, I managed to mess things up (luckily, it was a test directory). [The script I played with can be found here:
PowerShell Script to move folders one level up and delete the previous containing folder ]
It would be great if anyone can help me out with this. I would really appreciate it.
Thanks.
This should do it:
#echo off
setlocal enabledelayedexpansion
cd /d D:\XYZ
for /f "tokens=*" %%a in ('dir /b /ad') do (
if exist "%%a\%%a" (
xcopy /E "%%a\%%a\*" "%%a"
rd /s /q "%%a\%%a"
)
)
I'll go the PowerShell route. This has two options, by default it will remove any double folders so...
Z:\XYZ\John Doe\John Doe\My Documents\Stuff\Stuff\ItsAFile.txt
becomes:
Z:\XYZ\John Doe\My Documents\Stuff\ItsAFile.txt
If you only want to get rid of the first duplicate folder comment out the 6th line, and uncomment the 7th. If you don't like the reporting part remove/comment out the Write-Output lines.
$BasePath = "D:\XYZ"
gci $BasePath -recurse | %{
$OriginalFile = $_
If($OriginalFile.PSIsContainer){$FilePath = $_.FullName.ToString().Split('\')}
Else{$FilePath = $_.Directory.ToString().Split('\')}
for($i=1;$i -lt $FilePath.Count;$i++){ #Comment out this line to change to Base Path +2 folders method
# for($i=0;$i -lt $($BasePath.Split('\').Count +2);$i++){ #Uncomment to only affect the first 2 folders past the base path
if($filepath[$i] -and ($FilePath[$i] -ieq $FilePath[$i-1])){
$FilePath[$i-1] = $Null
}
}
($FilePath|?{$_}) -join '\'|%{
if($OriginalFile.PSIsContainer){
If(!($OriginalFile.FullName -ieq $_)){
Write-Output "Moving folder $($OriginalFile.fullname) to $_"
move-item "$($OriginalFile.fullname)\*" $_ -ErrorAction SilentlyContinue
Remove-Item $OriginalFile.fullname -ErrorAction SilentlyContinue}
}else{
If(!($OriginalFile.Directory.ToString() -ieq $_)){
Write-Output "Moving file $($OriginalFile.fullname) to $(Resolve-Path "$_\..")"
move-item $OriginalFile.fullname "$_\.." -ErrorAction SilentlyContinue
}}
}
}
To step through that, it:
Pulls a directory listing of each folder or file in the base path.
For each one it splits up the path based on the backslash character,
excluding file names.
It then steps through each segment comparing each folder to the one
before it in the path (or only steps the first few segments if you
go that route).
If the two sequential folders match it removes the first one.
It then rebuilds the path at the end of that process.
After that it compares the modified path to the original, and if
they are different it moves that item to the modified path.
It does handle files and folders differently, as it uses the .FullName property for folders, and the .Directory property for files.

Resources