Moving specific files by extension in Windows batch - batch-file

I'm very new to scripting in batch so please bear with me.
My goal is so as to move files which have the same filenames but with different extension; such as i want to move myfile.txt.1 and myfile.txt.2 without 'touching' myfile.txt
I've managed to use the wildcard * but it logically moves even the file which i don't want to move.(i.e. myfile.txt)
My question is... I was thinking of using a for loop to count files and using the "count" variable instead of the * , but is there a more direct way of implementing this script?
Attaching my script:
cd my_path
mkdir test
robocopy "src" "dest" "my_file.*"
echo The file was moved succesfully !!!!

I think robocopy should be able to handle your needs.
I would have expected the wildcard "my_file.txt.*" to work, but interestingly it still matches my_file.txt despite the lack of a trailing ..
But adding the /xf option to exclude the "undecorated" filename works for me:
robocopy "src" "dest" "my_file.txt.*" /xf "my_file.txt"

#ECHO OFF
SETLOCAL
SET sourcedir=c:\sourcedir
SET destdir=c:\destdir
FOR %%i IN ("%sourcedir%"\*.*) DO (
FOR %%n IN ("%%~ni") DO IF NOT "%%~xn"=="" IF EXIST "%destdir%\%%~nxi" (
ECHO CAN NOT MOVE "%%~fi" "%destdir%\%%~nxi"
) ELSE (ECHO MOVE "%%~fi" "%destdir%\%%~nxi")
)
GOTO :EOF
This should accomplish the task AAUI. It also detects the presence of a clashing filename in the destination directory. Simply remove the ECHO from the ECHO MOVE to activate after verifying your test. Personally, I'd leave the ECHO CAN NOT MOVE as-is to report a problem. Changing that to MOVE has the potential to overwrite an existing file.

Related

Why is my batch script hiding processed files/folders?

Can anyone here give me a hint, why my batch script marks successfully processed folders as system, hidden, non-archive? Furthermore I cannot even remove the "hidden" attribute via Explorer (probably because of the systemfolder attribute).
The script is meant to process one folder (passed to it as a parameter), looking for raw-photo files (.nef files in my case) that are marked read-only. For every read-only photo the script copies a specified file to the processed folder and renames that copy according to the photo filename.
The folder attribute mess is caused by robocopy. (Without that command there is no problem.) But it doesn't have to touch the folder at all. It only copies one file to that folder. The error only occurs, if at least one file in the folder was marked read-only and gets a sidecar file.
I already tried to move the script from system drive to desktop and start it from there. It made no difference.
(To avoid confusion: I am on a non-English Windows 10, so I used !var! instead of %var%. Hell it took some time to find that trick...)
echo off
setlocal ENABLEDELAYEDEXPANSION
chcp 65001
IF "%~1" == "" (
GOTO myWarning
) ELSE (
IF EXIST "%~1" (
GOTO myFuction
) ELSE (
GOTO myWarning
)
)
GOTO myFuction
:myWarning
echo Ordner-Pfad muss angegeben werden!
pause
GOTO:eof
:myFuction
echo Bearbeite %1
cd "%1"
for /r %%f in (*.nef) do (
set fileattr=%%~af
set readonlyattr=!fileattr:~1,1!
:: check if current file is read-only
IF !readonlyattr!==r (
:: create XMP-Sidecar file for read-only photos
echo %%f
robocopy "C:" "%1" "metadata-2stars.xmp"
rename "metadata-2stars.xmp" "%%~nf.xmp"
)
)
GOTO:eof
Sorry, after I narrowed the problem down to robocopy I found the solution. It seems to be a known bug in robocopy, e.g. described here:
https://blog.coeo.com/how-to-prevent-robocopy-from-hiding-your-files-and-how-to-fix-it-when-it-does
The solution/hotfix is simply to tell robocopy not to mark the destination as system hidden by adding /A-:SH at the end of the command. So with robocopy "C:" "%1" "metadata-2stars.xmp" /A-:SH everything works as expected.

Use multiple wildcards in a path in batch file

First of all, there are similar questions on Stack OverFlow like:
Windows - Batch file ignoring multiple wildcards
How to specify multiple wildcards in a folder directory in CMD
However, my use-case is a bit specific (or let's say: I couldn't manage to solve my problem using the lessons learned from the previous forum entries - mind that I am a pure beginner with Batch files).
What I want to do is to grab a file from a certain path, which includes a few subfolders (which change their names) - and copy it to another path which has similar folder structure.
I am currently stuck at the point, that I don't know how to set multiple wildcards in the source path, as it consists of a few things changing. Example:
File in Source:
C:\20170621_Update2017SR1\Polarion_update\_backup-20170627-1602.05\polarion\plugins\com.polarion.alm.tracker_3.17.0\configuration\MyPolarion\page.xml
Target Directory:
C:\Polarion\polarion\plugins\com.polarion.alm.tracker_3.18.2\configuration\My Polarion
Basically only the parts with numbers can change, so I was trying the following:
for /D %%a in ("C:\Polarion\polarion\plugins\com.polarion.alm.tracker*") do set "com.polarion.alm.tracker=%%a"
for /D %%b in ("C:\*_Update*\Polarion_update\_backup-*\polarion\plugins\com.polarion.alm.tracker*") do set "folder=%%b"
echo %com.polarion.alm.tracker%
echo %folder%
set source="%folder%\configuration\MyPolarion\page.xml"
set destination="%com.polarion.alm.tracker%\configuration\My Polarion"
xcopy /s /Y %source% %destination%
I am pretty sure line 2 of my Code contains mistakes - because I don't know if I can set multiple wildcards like this.
The console gives me for line 2:
Echo is on
I don't understand what it means and what should I do.
As I already mentioned in a comment, wildcards can only be used in the very last element of a path (independent on whether this is a file or directory). That is why your command line containing C:\*_Update*\Polarion_update\... fails. However, you can resolve every directory level with wildcards individually, like this:
set "folder="
for /D %%b in ("C:\*_Update*") do (
for /D %%c in ("%%~b\Polarion_update\_backup-*") do (
for /D %%d in ("%%~c\polarion\plugins\com.polarion.alm.tracker*") do (
set "folder=%%~d"
)
)
)
echo "%folder%"
If there are more than one matching directories on any levels, replace set "folder=%%~d" by echo "%%~d" to view them all.

Recursive rename isn't working at all in batch

So I have been searching in other topics how to rename files and folders in a .bat in a recursive way but it isn't working at all.
My code is:
# echo off
setlocal enabledelayedexpansion
set /p rut="Introduce folder: "
FOR /D /R %%x in ("%rut%"\*) DO (
cd %rut%
echo %cd%
pause
ren .\* "a"
)
exit
But this only renames the files that are on the first folder and not in the rest. Forfile won't work at all with the variables.
What I want to get is how I could rename everything inside the main folder (including subfolders) whatever it is, be it files or folders as "a" to solve the Windows problem of having routes way too long when trying to delete a full structure, that is why I can't use the ".txt" ".whatever" solution.
A powershell solution would be valid too!
Thank you very much
Edit I added a random to see if it was the name that was conflicting but no, it is still not working:
ren .\* "a%RANDOM%"
And renaming them from cmd works the same way, I mean, if I write ren "folder" "whatever" it will change but in the script doesn't work with "*"

Windows batch way to replace all files in subdirectories with singular file (copy, rename all files)

I have a good command over cmd commands, but this may require a variable or a loop which is where I fail in batch commands. Please help if you can!
-- Have about 100 subdirectories each has 1-20 HTML files in it. There are about 100 HTML files in the root directory too.
-- Need to replace all HTML files in the above directories with the same HTML source (copy over existing file and keep the name the same). Basically trying to replace all existing files with a redirect script to a new server for direct bookmarked people. We are running a plain webserver without access to server-side redirects so trying to do this just by renaming the files (locked down corp environment).
Seems pretty simple. I can't get it to work with wildcards by copying the same file over to replace. I only get the first file replaced, but the rest of the files will fail. Any one with any advice?
This should do it from the command prompt. Replace % with %% for use in a batch file.
for /r "c:\base\folder" %a in (*.html) do copy /y "d:\redirect.html" "%a"
Without knowing more precisely how you want to update the file content I suggest the following rough approach.
To re-create your example, I had to create some folders. Run this command to do that:
for /l %i in (1,1,20) do mkdir fold%i
I then used this script to create some example files:
#echo off
set number=0
for /d %%i in (c:\Logs\htmltest\*) do call :makefiles %%i
goto :EOF
:makefiles
set /a number+=1
touch %1\file%number%.txt
echo %number% >%1\file%number%.txt
I then used this script to append the text changed to the file. Not sure if that is what you wanted - probably you need something more sophisticated.
#echo off
set number=0
for /d %%i in (c:\Logs\htmltest\*) do #for %%f in ("%%i\*.txt") do call :changetext %%f
goto :EOF
:changetext
echo changing file contents to ^"changed^" for file: %1
echo changed>>%1

Batch: Copy files where include and exclude conditions are met

My requirement is to write a batch script that will compare the files in two folders. If a file exists in both SourceFolder and TargetFolder, then overwrite the file in TargetFolder with the file in SourceFolder.
Using a for-statement and an if-statement I can achieve this:
for /R %Source% %%G in (Prefix.*.ext) do (
if exist %Target%%%~nxG (
del %%G
copy %Target%%%~nxG %Source%
)
)
Although an additional requirement is to only copy files that start with 'prefix.' and end in '.ext' and also to exclude all files that contain the word 'exclude'.
In English: Copy all files from that source folder that start with 'Prefix.', end in '.ext', does not contain the text 'exclude'. and already exists in the target folder.
This is where I get stuck. Does anyone know how to do this in batch?
You can use xcopy for this. First, I am assuming that Prefix and ext are actual strings, to use variables instead you would have to wrap them like %Prefix%.
Second, you will have to make a new text file. Name it excludes.txt and put it in the same directory as your batch file. (If you don't want to make a batch file, then just put it in the directory that is active when you run the command). The only contents of this file should be your EXCLUDE string with no quotes, or other markup.
Ok, the command itself:
xcopy %Source%\Prefix.*.ext %Target% /U /EXCLUDE:excludes.txt
To break it down:
%Source%\Prefix.*.ext Selects the files in the source folder that start with Prefix and end with .ext
%Target% Specifies the destination for the files
/U Only copy files that already exist in the target directory
/EXCLUDE:excludes.txt This will read in excludes.txt and exclude any file that matches any part of the excludes.txt file.
That's it! This is probably easier than writing a FOR statement with a nested IF.
After reading this SO question, I ended up doing it like this. (Before the question got answered)
pushd %Target%
attrib +h *Exclude
for /R %%G in (Prefix.*.ext) do (
if exist %Target%%%~nxG (
del %%G
copy %Target%%%~nxG
)
)
attrib -h *Exclude
popd
The xcopy solution probably looks better although I'd prefer not to have to create (and remove) files if I can help it.

Resources