Nest if exist statement within for statement in batch file - batch-file

Good morning guys. I have a batch file that searches network PC user folders for XML files, then copies those files to a network location. However, it copies folders for all users, regardless of whether they have the files in question. What I would like to do is only make a folder for that user if the directory in which those files are contained exists.
Here is what the code looks like:
for /d %%g in ("\\computer.domain\c$\users\*") do (
xcopy /d /q /c /i /y "%%g\AppData\Roaming\Program\Folder\*.xml" "\\server.domain\shared_folder\%%g"
)
It works perfectly but for creating a user folder for every user. What I would like to do is only create a folder for users where Appdata\Roaming\Program\Folder contains XML files in the first place. I can't figure out how to get an if exists statement to work within that for statement though.
Also, this creates a directory structure like computer.domain/c$/users/user. If there is a way to strip out the c$/users (so it's computer.domain/user/file.xml), that would be even more amazing.
Thanks in advance!!
(Update) Here is the full code the batch is using. It repeats for each computer:
net use k: \\computer.domain\c$\users
for /d %%g in ("k:\*") do (
forfiles /P "%%g\AppData\Roaming\Program\Folder" /m *.xml /D -7 /C "cmd /C del #path"
)
net use k: /delete
for /d %%g in ("computer.domain\c$\users\*") do (if exist "%%g\Appdata\Roaming\Program\Folder\*.xml" (
xcopy /d /q /c /y "%%g\AppData\Roaming\Program\Folder\*.xml" "\\server.domain\shared_folder\%%~nxg\")
)
forfiles /P /S "M:\MAS500\endicia-postback-archive" /m *.xml /D -60 /C "cmd /C del #path"
The entire functionality is to delete XML files a week or older, then copy the remaining files, then delete files from the server that are two months or older. That line is only at the end, but the other lines are repeated for each computer.
Perhaps there is a better way to go about it? When I run it this way, it seems like I don't get a folder for all users that meet the criteria.
Thanks again!

Test this after altering the paths:
Just commenting here that your use of the /d switch will limit the files being copied.
#echo off
for /d %%g in ("\\computer.domain\c$\users\*") do (
if exist "%%g\AppData\Roaming\Program\Folder\*.xml" (
xcopy /d /q /c /y "%%g\AppData\Roaming\Program\Folder\*.xml" "\\server.domain\shared_folder\computer.domain\%%~nxg\"
)
)

Related

Batch script - dir /b is including directory names and empty lines in output file

I run this script to list backup files older than 8 days and delete them in a server, and it behaving weird recently. Please see below
::Find backup files older than 8 days
::/p Specifies the path from which to start the search.
::/s Instructs the forfiles command to search into subdirectories recursively.
::/d Selects files with a last modified date within the specified time frame.
::/c Carries out the command specified by String and then stops.
::/b Displays a bare list of directories and files, with no additional information.
PUSHD \\SERVER_NAME\M$\MSSQL
FORFILES /P Backup /s /d -8 /C "cmd /c dir /B #file">K:\ScriptLogs\OutPut
POPD
This was working fine recently until I created more folders inside \SERVER_NAME\M$\MSSQL\Backup like FULL, DIFF, LOG as
\\SERVER_NAME\M$\MSSQL\Backup\FULL
\\SERVER_NAME\M$\MSSQL\Backup\DIFF
\\SERVER_NAME\M$\MSSQL\Backup\LOG
And the K:\ScriptLogs\OutPut file is now including the folder name FULL as below
FULL
SERVER_NAME_DB_DIFF_2021_06_10_040135.diff
SERVER_NAME_DB_DIFF_2021_06_11_040124.diff
SERVER_NAME_DB_DIFF_2021_06_12_040213_1.diff
I'm not able to understand why it is including FULL in the output list (if my cmd is wrong it should include DIFF and LOG too).
And when i modified the code as below
PUSHD \\SERVER_NAME\M$\MSSQL
FORFILES /P Backup /s /d -8 /C "cmd /c dir /A-D /B #file">K:\ScriptLogs\OutPut
POPD
It gives error as below, and output file is not including FULL now (as /A-D excluded Dir's)
K:\DBScripts>PUSHD \\SERVER_NAME\M$\MSSQL
W:\MSSQL>FORFILES /P Backup /s /d -8 /C "cmd /c dir /A-D /B #file" 1>K:\ScriptLogs\OutPut
File Not Found
File Not Found
W:\MSSQL>POPD
My concern here is why it is including FULL directory name in the older code version and the code run gives error with new version. Thanks for your help.
Thanks #compo ....
PUSHD \\SERVER_NAME\M$\MSSQL
FORFILES /P Backup /S /D -%NUMBER_OF_DAYS% /C "cmd /Q /D /C \"If #IsDir==FALSE For %%G In (#File) Do Echo %%~G\"" 1>K:\ScriptLogs\OutPut-%dtStamp%
POPD
This fixed the issue.

Batch to search and move duplicate files of a specific type

There is a huge amount of pdf files in my datacenter's subdirectories. In a local folder i want to check if the existing files are already in the datacenter's dir and if yes to move them to another local folder.
I want to filter my search to .pdf files that have been modified today, otherwise the whole search thing in datacenter's subdirs takes ages.
#echo off
pushD \\server\pdf
for /r %%i in ( *.pdf ) do (
if exist "%userprofile%\desktop\F1\%%~nxi" ( move /y "%userprofile%\desktop\F1\%%~nxi" %userprofile%\desktop\F3
) else echo File %%~nxi is not a duplicate
)
popD
pause
What should i add to above for command ?
You already know about the ForFiles command, mentioning it in your duplicate question on DosTips; so why not use it?
PushD "\\server\pdf" 2>Nul && (
ForFiles /S /M *.pdf /D 0 /C "Cmd /C If Exist \"%UserProfile%\Desktop\F1\#File\" If Not Exist \"%UserProfile%\Desktop\F3\#File\" Move \"%UserProfile%\Desktop\F1\#File\" \"%UserProfile%\Desktop\F3\""
PopD)
If you prefer you could use Move with the /Y option or you could forget about the If Exist and just supress error messages, but the general idea should work for you.

Batch Script - FOR /D loop with wildcard folder issue

I have the following simple batch file:
FOR /D /r %%G IN (david\*\work) DO (
forfiles /P "%%G" /S /M *.* /D -7 /C "cmd /c del #PATH"
)
Problem is that it does not like the * as a wildcard in my path location in the first line, it says cannot find the path specified. I have multiple randomly named subfolders inside "david\" with a "work" folder in each of them -eg:
david\GSTR\work
david\WINDOWS\work
etc
How do I resolve this middle wildcard folder?
Note: even if I replace my command in the for loop with "echo %%G", it does not work.

Batch file to delete all text files in a folder over 10 days old except certain ones

I'm new to batch files, trying to write one that will delete all .txt files in a folder over 10 days old EXCEPT one called template.txt. How is this done? I have the below but it deletes ALL txt files over 10 days. Appreciate your help.
forfiles /p "C:\test" /s /m *.txt /c "cmd /c del #path" /d -10
Just implement the contition into the command line run by forfiles, like this:
forfiles /S /P "C:\test" /M "*.txt" /D -10 /C "cmd /C if #isdir==FALSE if /I not #file==0x22template.txt0x22 del #path"
The if #isdir==FALSE part is to exclude any directories from being processed further in case there are some with .txt at the end of their names (although quite unlikely), because forfiles enumerates both files and directories.
if /I not #file==0x22template.txt0x22 becomes if /I not "<name of currently iterated item>"=="template.txt" and excludes files named template.txt from being deleted. The /I option makes the comparison case-insensitive, like Windows also treats file and directory paths.

Delete folders with wild cards from a batch file Windows 7

I know we can write programs to do it.
I know we can write other scripts (perl/vbscript/ etc.) to do it.
I am looking for a command prompt/batch file solution to delete all folders matching sub_* (like sub_1, sub_2 ... ) to be deleted. rmdir or rd doesn't support wildcards, and I'm not able to figure out how to pipe the output of dir sub_*/ad command to delete command one by one as well. Any loop syntax etc. I can use?
for /d %x in (sub_*) do rd /s /q "%x"
You need to double the % if used in a batch file:
for /d %%x in (sub_*) do rd /s /q "%%x"
Untested, make sure to first use echo or something else that doesn't immediately wipe the directories ;)
forfiles /P C:\where\my\dirs\at /M sub_* /C "cmd /c if #isdir==TRUE rmdir /s /q #file"

Resources