Select folders alphabetically in batch file?

Hi All,

I am trying to create a batch file that creates symbolic links based on a selection of folders.  The problem I am having is selecting the folders that I want to create the symbolic links from.

Here is an example of what I mean.  I have Drive P: which has the following folders:

Pathfinder
Pathology
Patton
Paul
Payback

What I want to do is for symbolic links to be made from say Pathfinder to Patton alphabetically.  The code I currently have is here and can only select a folder based on a name filter.  Is there a filter or way of sorting that will allow me to do this?  This is the code I have.
SET target="C:\Downloads\Symlink"
SET filter="Music"

forfiles /s /m %filter% /c "cmd /c IF @isdir==TRUE mklink /D %target%\@relpath %cd%\@relpath"

Open in new window

LVL 1
robclarke41Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Steve KnightIT ConsultancyCommented:
I prefer using a for loop with output of dir command as then you can control it fully. Remove the capitalised ECHO to do the commands, at the moment it will show them only.

If you can get dir command to show you what you want, e.g.

dir /b /s /ad  will show all dirs under a subdir
dir /b /s /ad music* will show all dirs under a subdir starting with music

@echo off
SET target=C:\Downloads\Symlink
SET filter=*

REM Bare dir listing of all dirs only under the current starting dir
Set Dir=dir /b /ad %filter%

for /f "tokens=*" %%A in ('%dir%') do ECHO mklink /D "%target%%%~pnA" "%%~fA"

Open in new window


Add /s to the Dir variable to do it for all subdirs like your forfiles command
Change filter to Music* to pick out just ones with Music in the name.

Steve

[Edit meant to use %dir% not %dircmd% as variable as %dircmd% is reserved]
0
robclarke41Author Commented:
Thanks Steve so how do I select a range alphabetically? This is what I'm trying to achieve.
0
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
With a filter of Pat* you will get only those folders. If you need a more complex filter than one using simple pattern matching, you'll need more effort. E.g. for including Paul:
@echo off
SET target=C:\Downloads\Symlink

for /f "tokens=*" %%A in ('dir /b /a:d Pa* ^| findstr /b "Pa[tu]" ') do ^
for /F "tokens=*" %%B in ('dir /b /s %%A\') do ECHO mklink /D "%target%%%~pnB" "%%~fB"

Open in new window

0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

QlemoBatchelor, Developer and EE Topic AdvisorCommented:
With a more specific selection by just enumerating dirs to use, just write up those in a FOR:
@echo off
SET target=C:\Downloads\Symlink

for %%A in (Pathfinder Patton Payback) do ^
for /F "tokens=*" %%B in ('dir /b /s %%A\') do ECHO mklink /D "%target%%%~pnB" "%%~fB"

Open in new window

0
robclarke41Author Commented:
Thanks for all the help! How would I do this as a range though rather than specifying the folders? So for example I could include all folders from pathfinder to payback?
0
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
The first code snippet I posted does show that. You need to know what is in common, as ranges can only be defined if you are able to provide a valid regular expression (complex) or simple pattern for pattern matching (more obvious and easy). dir can only use simple pattern matching using ? for "any arbitrary character at this position" and * for "any amount (including zero) of arbitrary characters here". findstr can be used to apply more complex filtering using RegEx.

Another idea, and that is probably what you are after and in need for e.g. going thru "Pathfinder" to "Obsolete" and hence having a real range of consecutive names you cannot describe well with RegEx:
@echo off
SET target=C:\Downloads\Symlink
set first=Obama
set last=Reagan
set matched=

for /D %%A in (*) do (
  if "%%A" == %first" set matched=yes
  if defined matched for /F "tokens=*" %%B in ('dir /b /s %%A\') do ECHO mklink /D "%target%%%~pnB" "%%~fB"
  if "%%A" == "%last%" set matched=
)

Open in new window

This ignores all folders until reaching the "first" one. It then goes thru all subfolders. If "last" is hit, no more subfolders will get processed (while still checking for the folder names unnecessarily to keep it "structured programming" without using goto).
0
robclarke41Author Commented:
Thanks for this Qlemo, I'm getting 'The syntax of the command is incorrect' when running the script though?  Is there something else I need to do?
0
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
I had two typos in my code:
@echo off
SET target=C:\Downloads\Symlink
set first=Obama
set last=Reagan
set matched=

for /D %%A in (*) do (
  if "%%A" == "%first%" set matched=yes
  if defined matched for /F "tokens=*" %%B in ('dir /b /s %%A\') do ECHO mklink /D "%target%%%~pnB" "%%~fB"
  if "%%A" == "%last%" set matched=
)

Open in new window

Of course you then need to change the values for "first" and "last" in lines 3 and 4 to your respective folder names.
0
robclarke41Author Commented:
Thanks, the script now runs without any errors (I have also changed the first/last values).  However nothing happens?  In the C:\Downloads\Symlink directory there is nothing?
0
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
The script looks in the current directory, and probably that is not where your folders are. You can provide the full or relative path in line 7, but we then need to modify the script slightly:
@echo off
set src=C:\Temp 
set target=C:\Downloads\Symlink
set first=Obama
set last=Reagan
set matched=

for /D %%A in (%src%\*) do (
  if "%%~nxA" == "%first%" set matched=yes
  if defined matched for /F "tokens=*" %%B in ('dir /b /s %%A\') do ECHO mklink /D "%target%%%~pnB" "%%~fB"
  if "%%~nxA" == "%last%" set matched=
)

Open in new window

%src% now contains the path to the folders to check.
0
Steve KnightIT ConsultancyCommented:
Qlemo, presumably if you didn't find Obama or Reagan then it wouldn't start and/or complete?

Perhaps using GEQ instead of == for the first IF's, and GTR for the second and stopping, i.e.

for /D %%A in (%src%\*) do (
  if "%%~nxA" GEQ "%first%" set matched=yes
  if "%%~nxA" GTR "%last%" exit /b
  if defined matched for /F "tokens=*" %%B in ('dir /b /s %%A\') do ECHO mklink /D "%target%%%~pnB" "%%~fB"
)

Open in new window


But I'm still confused what is wanted as such?  The original code suggested subdirs, and this code is now filtering on the top level dirs then making a link for each dir under that.  If only creating a link at the top level then you should only need the top level dir link created, i.e.

for /D %%A in (%src%\*) do (
  if "%%~nxA" GEQ "%first%" set matched=yes
  if "%%~nxA" GTR "%last%" set matched=
  if defined matched ECHO mklink /D "%target%%%~pnA" "%%~fA"
)

Open in new window


Can you give us examples of the folder structure showing which dirs you do/don't want including please?

Steve
0
robclarke41Author Commented:
Hi Steve,
Sure no problem.  So I have a network drive mapped to a NAS unit, the drive is mapped as P:

P:\ has several subfolders ranging from A-Z alphabetically.

I want to make Symbolic Links of a range of these folders, say from Alpha to Papa.  The reason I cannot include the entire folder is that I want to sync the data from the range to an external disk.  I cannot run the sync on the entire disk as there is nowhere near enough space.

So if I could specify in the script the from folder and the to folder in the range alphabetically and have the script make symbolic links for all of those folders in the target location we have a winner!

I hope that makes sense?!

Thanks for your help so far guys.
0
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
My bad. Of course a symbol link to the top level folders is correct. So Steve's last code is appropriate, even allowing providing (inclusive) limits for folder names which do not really exist, like "Pa" to "Quo". Putting it together:
@echo off
set src=C:\Temp 
set target=C:\Downloads\Symlink
set first=Obama
set last=Reagan
set matched=

for /D %%A in (%src%\*) do (
  if "%%~nxA" GEQ "%first%" set matched=yes
  if "%%~nxA" GTR "%last%" set matched=
  if defined matched ECHO mklink /D "%target%%%~pnA" "%%~fA"
)

Open in new window

or
@echo off
set src=C:\Temp 
set target=C:\Downloads\Symlink
set first=Obama
set last=Reagan
set matched=

for /D %%A in (%src%\*) do if "%%~nxA" GEQ "%first%" if "%%~nxA" LEQ "%last%" ECHO mklink /D "%target%%%~pnA" "%%~fA"

Open in new window

0
Steve KnightIT ConsultancyCommented:
On a different level though.... are you making these symbolic links to part of the drive so that you can then do a robocopy or something?

Steve
0
robclarke41Author Commented:
Hi Guys, I just ran again and rather encouragingly I got the following:
mklink /D "C:\Downloads\Symlink\Alpha" "c:\Alpha"
mklink /D "C:\Downloads\Symlink\Beta" "c:\Beta"
mklink /D "C:\Downloads\Symlink\Books" "c:\Books"
mklink /D "C:\Downloads\Symlink\Charlie" "c:\Charlie"

Open in new window

Strangely though nothing happened, I did run a single line to make sure symbolic links were working etc. and it worked fine so I'm not sure what's happening here?

Steve, yes I use an app called Allway Sync that should work fine with this setup.  Just need these link sorted!
0
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
We still have the ECHO in place here, so the command will not be executed, only echoed to the screen. Remove ECHO to allow to perform the magic!
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
robclarke41Author Commented:
Now I'm confused! If I take the ECHO out I get:

 
The system cannot find the path specified.
The system cannot find the path specified.
The system cannot find the path specified.

Open in new window


Doesn't make sense as with the ECHO on it seems to be performing the right tasks as above?
0
robclarke41Author Commented:
Just to let you know how I'm testing:

set src=C:\
set target=C:\Downloads\Symlink
set first=Alpha
set last=Charlie
set matched=

for /D %%A in (%src%\*) do (
  if "%%~nxA" GEQ "%first%" set matched=yes
  if "%%~nxA" GTR "%last%" set matched=
  if defined matched mklink /D "%target%%%~pnA" "%%~fA"
)

Open in new window



I have folders:

C:\Alpha
C:\Beta
C:\Charlie

Each folder has data in.

After running the above script I am expecting to see symbolic links appearing in the C:\Downloads\Symlink folder but I get a 'cannot find the path' error.  This is now a step in the right direction but also confusing.  If I manually create a C:\Downloads\Symlink\Alpha folder the script then works perfectly for the Beta and Charlie folders and create the symbolic links.  However the Alpha folder is just the folder I manually created.  So the script is working when I manually create the first folder?!
0
robclarke41Author Commented:
Must be me I tried it again and it's working! Thanks guys, you are legends!
0
Steve KnightIT ConsultancyCommented:
No problem, glad we got there!
0
robclarke41Author Commented:
Sorry guys one more question! The script works great for the range I wanted but how would I get the script to just include all files and folders in a directory?
0
Steve KnightIT ConsultancyCommented:
I would say create a link to the dir above? Do you mean a link to each file individually?
0
robclarke41Author Commented:
Sorry no just a link to every folder in a directory. Like above but just a way of including everything rather than specifying a range?
0
Steve KnightIT ConsultancyCommented:
You should be able to use my original script for that, on phone at no. But think was second one.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Windows Batch

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.