I have Directory A, which contains a bunch of subdirectories, and empty Directory B. I would like to create a .bat file that symlinks all of the subdirectories inside Directory A whose names contain "april" (only the top-level ones) into Directory B. Is this possible?
What I have so far is:
echo off
setlocal EnableDelayedExpansion
title Updating Directories...
if exist "C:\path\to\directory\a" (
echo Updating Directories...
set "dira=C:\path\to\directory\a"
set "dirb=C:\path\to\directory\b"
for /f "usebackq delims=|" %%f in (`dir /b "!dira!"`) do (mklink /d "!dirb!\%%f" "!dira!\%%f")
title Symlinks Created^^!
echo Done^^!
pause
) else (
echo Cannot find Parent Directory.
pause
)
This works, but it symlinks all of the subdirectories inside Directory A into Directory B. Is there a way I can, for example, search for top-level directories whose names contain "april," return the list, and then only symlink those?
Not sure why you want a batch file. Just type the command.
for /f "delims=" %A in ('dir /b /ad "%userprofile%\desktop\*u*.*"') Do mklink /d "%userprofile%\desktop\b\%~nxA" "%A%
This create a link in a folder called B on the desktop (so create it first) for any folder on the desktop that contains the letter u in the name. See dir /?.
Note in Windows (NT family) the wildcard operators are regular expressions unlike Dos.
?*net*.* shows all files that contain net, but don't begin with net.
Thanks to #CatCat I was able to figure it out. Here's what's now working, for posterity's sake:
echo off
setlocal EnableDelayedExpansion
title Updating Directories...
if exist "!userprofile!\path\to\directory\a" (
echo Updating Directories...
set "dira=!userprofile!\path\to\directory\a"
set "dirb=!userprofile!\path\to\directory\b"
for /f "usebackq delims=|" %%f in (`dir /b "!dira!\*april*.*"`) do (mklink /d "!dirb!\%%f" "!dira!\%%f")
title Symlinks Created^^!
echo Done^^!
pause
) else (
echo Cannot find Parent Directory.
pause
)
Related
I have been trying to make symbolic links from multiple sources.
I have a reg.txt file in the new directory as well as the sort.bat.
the reg.txt :-
redcar1=123456
greencar2=345678
In directory called vehicles with sub directories of 'reg_numbers' ie:- 123456,
within that directory I have a sub directory called keys, or key, with a *.txt file.
I want to symbolic link all the 'reg_numbers' (parsing the reg.txt - changing the folder name in the process) directories into the new directory the sort.bat file is in, and all the keys or Key directory files (*.txt), into a common keys directory in the new folder
so say:-
D:\vehicles\123456\keys\this.txt
D:\vehicles\345678\key\that.txt
symbolic linked
e:\new\redcar1\
e:\new\greencar2\
e:\new\keys\this.txt
e:\new\keys\that.txt
sort.bat is in the new folder.
#echo off
setlocal EnableDelayedExpansion
set NEWPATH=%~dp0
set OLDPATH=d:\vehicles
for /f %%d in ('dir /b %NEWPATH%\keys') do (
if not "%%d"=="not.txt" del /Q "%NEWPATH%Keys\%%d" ::clean out files
)
for /f "tokens=1,2 delims==" %%a in (reg.txt) do (
rmdir /Q "%NEWPATH%%%a" ::clean out dir
mklink /D %NEWPATH%"%%a" %OLDPATH%\"%%b"
for /f %%c in ('dir /b %OLDPATH%\%%b\keys' ) do (
mklink %NEWPATH%Keys\"%%c" %OLDPATH%\"%%b"\"%%c"
)
)
It's probably a mess but it works for nearly everything but I cannot get the that.txt from key folder.
#echo off
setlocal EnableDelayedExpansion
set "NEWPATH=%~dp0"
set "OLDPATH=D:\vehicles"
for /f %%A in ('2^>nul dir /b /a-d "%NEWPATH%\keys"') do (
if not "%%~A" == "not.txt" del /Q "%NEWPATH%\Keys\%%~A"
)
for /f "usebackq tokens=1,2 delims==" %%A in ("%NEWPATH%\reg.txt") do (
rmdir /Q "%NEWPATH%\%%~A"
mklink /D "%NEWPATH%\%%~A" "%OLDPATH%\%%~B"
for /f %%C in ('2^>nul dir /b "%OLDPATH%\%%~B\keys" "%OLDPATH%\%%~B\key"' ) do (
mklink "%NEWPATH%\Keys\%%~C" "%OLDPATH%\%%~B\%%~C"
)
)
This may help to get symlinks to the files this.txt and that.txt. You have a keys folder and a key folder, yet your code only searches the directory of one of them. So now dir will search both directories.
I also adjusted quoting and use ~ in the for variables to remove possible quotes. Backslashes added as path separators where needed.
The double quotes for the set commands is to ensure that the value does not include any trailing space that is invisible to see.
2^>nul in the for commands is to redirect stderr stream to nul, so output of no files found by dir will not be output.
usebackq in for options changes the rules for the command. Double quotes without usebackq, interprets a double quotes as a string, not a path. With usebackq, double quotes can be used on a path. %~dp0 is a path that may have spaces so double quoting seems a good idea to add. View for /? for more help.
I have a Directory with a deep Directory->Sub-directory tree structure. I need to write a batch file to copy all the numbered files (files with names as digits and no alphabetic characters) from all the sub-directories.
For example, a sub-directory might contain the following files:
WR10091.txt
AX10091.htm
10091.txt
AX10091.xml
10091.xml
I need to copy 10091.txt and 10091.xml to another location. I can copy files like AX10091.xml and AX10091.htm by specifying AX*.*. But I cannot figure out how to copy just numbered files with no alphabetic characters. There are thousands of directories and the directory structure does not have any pattern (the depth of a tree branch can vary considerably).
Any help will be appreciated.
#echo off
setlocal enableextensions disabledelayedexpansion
set "source=%cd%"
set "target=x:\target\folder"
for /r "%source%" %%a in (*) do (
(for /f "delims=0123456789" %%b in ("%%~na") do (
break
)) || echo copy "%%~fa" "%target%"
)
In this code the for %%a will iterate over all the files under the indicated folder. For each of them, the for /f %%b will try to tokenize the file name (%%~na) using numbers as delimiters. If the file name only contains numbers, there will be nothing to process (only delimiters) and the inner for raises errorlevel. This is checked with conditional execution (the code after the || is executed if the previous command fails) and if errorlevel was raised the copy operation is echoed to console.
If the output is correct, remove the echo to perform the copy.
note: the break in the inner for loop is included just to have a command that does nothing when files with non numeric names are found.
#echo off
for /f "tokens=* delims=" %%a in ('dir /b /s /a:-d "*"') do (
echo %%~na|findstr /e /b /r "[1-9]*" >nul 2>nul && (
copy %%~fa c:\somewhere\
)
)
should be executed in the same directory as the files.
for /f "delims=" %%a in ('dir /b/s/a-d ^| findstr /reic:"\\[0-9][0-9]*\..*" /c:"\\[0-9][0-9]*"') do copy "%%~a" "targetDir"
This might not work with XP and/or Vista, but this can be fixed if needed (see What are the undocumented features and limitations of the Windows FINDSTR command).
I'm trying to figure out how to match folders with a dot in the file name (e.g., ".svn") in a Windows batch script.
Here's the basic script:
setlocal
pushd c:\myDir
#echo off
FOR /D /r %%G in ("*\.whatever") DO (
echo %%G
REM do stuff
)
#echo on
popd
endlocal
This works just fine for most folder names (e.g., "*bin"), but I can't figure out the method to specify a folder with the dot. "*.whatever" and "*\.whatever" return no results. I'm guessing I'm missing some escape character or something equally simple, but I haven't been able to find any documentation on it.
(Before anyone asks, no I'm not trying to recursively delete subversion folders; "*.svn" is just an example.)
Maybe I am missing something, but as you say it seems simple
for /r /d %%a in (.*) do echo %%~fa
But if the folders are hidden, the normal for will not be able to see them, so we need to execute a dir command an process its output with a for /f
for /f "delims=" %%a in ('dir /ad /s /b .*') do echo %%~fa
I need to copy a file and paste it in many directories, can I do this with a single command in windows prompt?
I tried this code, but it didn't work:
> copy C:\main\folder-1\docs\file.txt C:\main\*\docs
The names are illustratives, but the idea is: inside the "main" folder I have 50 folders ("folder-1", "folder-2", ..., "folder-50")... and inside each "folder-N", I have other folder named "docs". Every time that I create a file into any "folder-N\docs" I need to paste it into all "folder-N\docs".
Is it possible? or I really need to paste the file, folder by folder?
Straight up from the command line:
for /D %x in (c:\main\*.*) DO COPY c:\main\folder-1\docs\file.txt %x\docs\file.txt
From a BAT file or CMD file (not from the command line), you need to escape the % variable again
for /D %%x in (c:\main\*.*) DO COPY c:\main\folder-1\docs\file.txt %%x\docs\file.txt
Of course, if the subdirectory "docs" directory doesn't exist in each subfolder of "main", the iteration will print an error. That's why in my example above I explicitly specify copying to %x\docs\file.txt. If I had just said `%x\docs" as the target of the copy, it might create a file called "docs" that contains the contents of the file.txt source.
More information on for loops here and here:
Or just type "help for" at the command prompt.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir\one"
:: Build list of directorynames
SET "dnames="
FOR /f "delims=" %%a IN ('dir /b /ad "%sourcedir%" ') DO (
IF EXIST "%sourcedir%\%%a\docs\" SET "dnames=!dnames! "%%a""
)
FOR %%a IN (%dnames%) DO FOR %%b IN (%dnames%) DO IF NOT %%a==%%b (
FOR %%s IN ("%sourcedir%\%%~a\docs\*") DO (
IF NOT EXIST "%sourcedir%\%%~b\docs\%%~nxs" ECHO(COPY "%sourcedir%\%%~a\docs\%%~nxs" "%sourcedir%\%%~b\docs\%%~nxs"
)
)
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
The required COPY commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(COPY to COPY to actually copy the files.
I'd suggest that you create a testing subtree of a few small subdirectories before releasing in anger. Remember that this "report" may say to copy the same file from dir1 and dir5 into dir3 but when released because the file would actually be copied from dir1 to dir3, the copy from dir5 would not occur (when the copy from dir5 is checked, the copy from dir1 would already have occurred.)
You could suppress the copy report by appending >nul to the copy line.
Note that this routine is oriented towards one-file-at-a-time and showing what should be done. This following routine should do the same thing, is shorter but doesn't provide an elegant testing structure:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir\one"
:: Build list of directorynames
SET "dnames="
FOR /f "delims=" %%a IN ('dir /b /ad "%sourcedir%" ') DO (
IF EXIST "%sourcedir%\%%a\docs\" SET "dnames=!dnames! "%%a""
)
FOR %%a IN (%dnames%) DO FOR %%b IN (%dnames%) DO IF NOT %%a==%%b (
ECHO(xcopy /d "%sourcedir%\%%~a\docs\*" "%sourcedir%\%%~b\docs\"
)
GOTO :EOF
Again, the xcopy is reported, not executed for testing purposes.
I'm currently trying to write a .cmd Windows Shell script that would iterate over a set of folders. However even the following simplest script:
echo "%ROOT%"
for %%f in ("%ROOT%\Binaries\" ) do (
echo "%%f"
if not exist "%%f\Subfolder"
md "%%f\Subfolder"
)
outputs:
CurrentDir>echo "<ActualPathToRoot>"
"<ActualPathToRoot>"
%f\Subfolder was unexpected at this time
CurrentDir>if exists "%f\Subfolder"
What am I doing wrong? How do I alter that script so that it iterates over that one folder and once it see there's no subfolder named "Subfolder" it creates that subfolder? Also is there a good tutorial on writing such scripts?
For (sub)folder-iteration you need to use a different for parameter.
So if you want to list all directories of C: you should do this:
for /d %%A in (C:\*) do echo %%A
Note the parameter /d which indicates a directory. To go into subdirectories you need to do a recursive for with /r
for /r C:\Windows %%A in (*.jpg) do echo %%A
This would iterate through all Windows subdirectories looking for JPGs. Low behold you should be able to do /d /r and this reference suggests you can - I simply can't, but maybe you are able to do this?
A workaround I quickly jotted down is to just do a dir of all directories in a for loop:
for /f "delims=" %%A in ('dir /ad/s/b') do echo %%A
Note that dir is used in conjunction with /ad/s/b which performs a recursive listing of directories, printing the names of the directories found.
With these tools in your hand you should be able to do your if-subfolder construct. Note that you might need
This works for me:
echo %ROOT%
for /D %%f in (%ROOT%\Binaries\*) do echo %%f && if not exist %%f\Subfolder md %%f\Subfolder