Group in folder

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
BijaN-R
Posts: 7
Joined: 19 Aug 2013 10:30

Group in folder

#1 Post by BijaN-R » 19 Aug 2013 13:50

Hey guys

I need some commands in registry

Code: Select all

HKEY_CLASSES_ROOT\*\shell\Group\Command

to make a new folder and move selected items in this folder, so that seems like these files are grouped in one folder.

I guess this should be some thinks like this:

Code: Select all

cmd /k mkdir %1|For %1 do move "%1" .\%1


Please tel me how can I do this.

Thanks.

Endoro
Posts: 244
Joined: 27 Mar 2013 01:29
Location: Bozen

Re: Group in folder

#2 Post by Endoro » 20 Aug 2013 00:46

please explain exactly what registry key you mean.
Btw. it is not necessary and desired to write the whole text in bold letters.

BijaN-R
Posts: 7
Joined: 19 Aug 2013 10:30

Re: Group in folder

#3 Post by BijaN-R » 27 Aug 2013 01:19

Sorry for my bold texts.

As you know in this registry key we can add items to files context menu:

Code: Select all

HKEY_CLASSES_ROOT\*\shell\

and put the command of this item to this key:

Code: Select all

HKEY_CLASSES_ROOT\*\shell\My Item\Command


So I need some commands to select several files and move them to one new folder (I prefer name of the selected file for folder name or something like groupe+time)

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Group in folder

#4 Post by foxidrive » 27 Aug 2013 02:52

Do you want a batch file?

If there is a group of files then you have to pick which name to use as the folder name.

penpen
Expert
Posts: 1996
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Group in folder

#5 Post by penpen » 27 Aug 2013 07:24

If you want to do something like this:

Code: Select all

cmd /E:ON /F:ON /C "@for %%s in ("%1") do @for %%t in ("%%~dpsnew Folder") do @(@if exist "%%~t" @(@for /F "tokens=1 delims=dD" %%a in ("%%~at") do @(@if not "%%~at" == "%%~a" @(move "%%~s" "%%~t"))) else @(@(@md "%%~t") && @(@move "%%~s" "%%~t")))"
resulting in such a "My Item.reg":

Code: Select all

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\My Item\Command]
@="cmd /E:ON /F:ON /C \"@for %%s in (\"%1\") do @for %%t in (\"%%~dpsnew Folder\") do @(@if exist \"%%~t\" @(@for /F \"tokens=1 delims=dD\" %%a in (\"%%~at\") do @(@if not \"%%~at\" == \"%%~a\" @(move \"%%~s\" \"%%~t\"))) else @(@(@md \"%%~t\") && @(@move \"%%~s\" \"%%~t\")))\""
then you should note that,
if you select a group of files and click "My Item" in the context menue,
then the command above is executed per file,
and so the command never sees groups of files.

Dynamically named directories are in such a case useless, as the result were one file per directory.
So the above static named directory is the best you can do with batch using a single context menu item.

penpen

BijaN-R
Posts: 7
Joined: 19 Aug 2013 10:30

Re: Group in folder

#6 Post by BijaN-R » 05 Sep 2013 11:32

Thanks penpen and foxidrive

Dear penpen I used your commands and it worked.

I was made something like this, but sometimes selected files were merged to one file.

Code: Select all

cmd /c md group|move "%1" group


So I changed Command to this (I add ping as timer to have enough time for creating folder before moving files)

Code: Select all

cmd /c md group&&ping 127.0.0.1 -n 1&move "%1" group&&ping 127.0.0.1 -n 1


Except of merge issue, folder name is still problem yet. My command and yours too has one static name for folder (group||new folder) but if we do this "group act" several times all files gone to this one single folder instead of separated folders for each time.

How we can use something like %TIME% or %RANDOM% for folder name ?

http://cult.yzi.me/up_files/forums/Group%20in%20folder.reg

Help me please, and sorry for my English.

Image

penpen
Expert
Posts: 1996
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Group in folder

#7 Post by penpen » 05 Sep 2013 14:35

Some notes:
The issue of merging files, is caused by the | character.
It causes the command line processor (CLP) to spawn 2 threads:
one executing "md group", and the other executing "move "%1" group".
Both are working in (pseudo)parallel threads, so if the second is performed first,
it renames the file,
and after that has happened all other group operations should merge
(if COPYCMD variable contains /Y), as "md" fails (name is a filename),
and "move" overwrites group as the target is no path.

Your fix with the added ping commands only seems to be corrected by the ping, but it is fixed,
because there you are using an & instead of an |.
The & advices the CLP to execute the commands inorder, first the left command and then,
after the first is finished the right one.
But if you create a file named "group" you will see, that it will do the same, as the above command line.

BijaN-R wrote:How we can use something like %TIME% or %RANDOM% for folder name ?
Just use the escaped form of %, this means %%TIME%% and %%RANDOM%% should work.
But the problem is, if you are using dynamically created directory names with unique ids,
then every file will be placed in its own directory.
The cause: The command you build is called for every single file. The program cannot guess,
that you wanted to group some files.

You can try it out using on a group of selected files:

Code: Select all

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\My Item\Command]
@="cmd /E:ON /F:ON /C \"@for %%s in (\"%1\") do @for %%t in (\"%%~dnew Folder (%%time%%)\") do @(@echo md group ^& move \"%%~s\" \"%%~t\" & pause)\""
This only displays the move operation that would be performed;
if you want no simulation, remove the echo and replace the ^& by &.
Using %%random%% should be similar (random values, but should all be different).

The only 2 things you could do were:
1) to create 2 or 3 context menu items:
1: "create file group", as system variables will be discarded, when cmd session ends, you have to use a (temp) file
2: "move group" i then would create Folders of the form "new Folder (n)" while n is increasing in [0:2^31-1]
3: "add file(s) to group"

2) to create a program that can self check if an instance of itself has been started, which you can pass a stream of filenames,
and if this stream doesn't contains a minimum names per second (you have to specify),
then it performs the grouping operation (again of the above form), and exits.

The second solution is far beyond batch file scripting.
Actually i cannot see another solution for this problem.

Btw:
BijaN-R wrote:... and sorry for my English.
This is no problem as my use of the english language is as bad, too :D (And this assums that i have a good day.)
.

penpen

BijaN-R
Posts: 7
Joined: 19 Aug 2013 10:30

Re: Group in folder

#8 Post by BijaN-R » 06 Sep 2013 02:41


Hi penpen,

You know my batch scripting skill is poor, I think if we can do something like:

Code: Select all

set foldername=%%time%%

then use %%foldername%% instead of %%time%% our folder name can still unique on each grouping we do, off course if it was a batch file not registry.


BijaN-R
Posts: 7
Joined: 19 Aug 2013 10:30

Re: Group in folder

#9 Post by BijaN-R » 06 Sep 2013 06:37


I did some search and I find that if I want do something on multiple files, using "Send to" menu in better option.
So I create these batch files but they doesn't work.

Code: Select all

set FNAME=%DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2% [%TIME:~0,2%.%TIME:~3,2%.%TIME:~6,2%]
md "%FNAME%"
FOR /F "tokens=*" %%v IN ('dir /b') DO @move "%%v" %FNAME%

Code: Select all

set FNAME=%DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2% [%TIME:~0,2%.%TIME:~3,2%.%TIME:~6,2%]
md "%FNAME%"
FOR /F "tokens=*" %%v IN (*.*) DO @move "%%v" "%FNAME%"

Code: Select all

set FNAME=%DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2% [%TIME:~0,2%.%TIME:~3,2%.%TIME:~6,2%]
md "%FNAME%"
FOR /F "tokens=*" %%v IN (%1) DO @move "%%v" "%FNAME%"


Folder is created nicely but move part of this batches are wrong.
This is Send to folder address:

Code: Select all

%appdata%\Microsoft\Windows\SendTo


BijaN-R
Posts: 7
Joined: 19 Aug 2013 10:30

Re: Group in folder

#10 Post by BijaN-R » 06 Sep 2013 07:51


Hey buddy, it worked (in sendTo menu):

Code: Select all

@ECHO OFF
SET FNAME=%DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2% [%TIME:~0,2%.%TIME:~3,2%.%TIME:~6,2%]
md "%FNAME%"

SETLOCAL

:LOOP
IF (%1) EQU () GOTO END
move %1  "%FNAME%"
SHIFT
GOTO LOOP

:END
ENDLOCAL


You can use it for registry shell menu too, just copy this batch file into windows folder and put this in Command value (if file name is Group.bat):

Code: Select all

Group "%1"

Do it for files (*) and Folder in registry.

[Some issue still exist in shell menu]:

    • It work only for 15 files but for more than 15 it will disappear.
    • It open A command window for each file and there is risk of creating two folder if process take more than 1sec (I don't know, not happened yet).

But sendTo menu is ok.

penpen
Expert
Posts: 1996
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Group in folder

#11 Post by penpen » 06 Sep 2013 11:55

Hi there.
BijaN-R wrote:[Some issue still exist in shell menu]:
• It work only for 15 files but for more than 15 it will disappear.
• It open A command window for each file and there is risk of creating two folder if process take more than 1sec (I don't know, not happened yet).
The 15 file limit is curious... there should be no limit.
The only limitation to this should be, that you cannot add Folders to this selection.
One of my PC's is slower and it happens regularly that there are created 2-4 folders for 32 sample files.

Using the "send to" menu is a great idea.
I have some minor changes to the batch file:
The date format is localized, and therefore you may get strange name results on other PC's,
so i've changed it to "new Folder[ (N)]" format.
A for loop is (only) slight faster than the ":label" "goto label" solution.
The errors should be displayed.

Code: Select all

@echo off
setlocal
set /A "N=1"
for /F "tokens=* delims=" %%a in ('dir /b "%~dp1new Folder*" 2^>nul') do set /A "N+=1"
for /L %%a in (%N%,-1,1) do if not exist "%~dp1new Folder (%%a)" set "FNAME=%~dp1new Folder (%%a)"
if not exist "%~dp1new Folder" set "FNAME=%~dp1new Folder"

md "%FNAME%" || (
   echo Could not create the directory "%FNAME%": Abort grouping.
   pause
   goto :eof
)
for %%a in (%*) do (
   move "%%~a" "%FNAME%" || (
      echo Error on: move %%~a "%FNAME%"
      pause
   )
)

penpen

Edit: I have removed the false improvement note: "Added "'s so files/folders with spaces are allowed to move, and ",
as the referred batch script has no problem with space containing filenames, sorry for that.
Last edited by penpen on 06 Sep 2013 16:56, edited 1 time in total.

BijaN-R
Posts: 7
Joined: 19 Aug 2013 10:30

Re: Group in folder

#12 Post by BijaN-R » 06 Sep 2013 15:45


Hi penpen

penpen wrote:A for loop is (only) slight faster than the ":label" "goto label" solution.


I'm new in batch file things.
I know c and java but nested If and for loops of batch files and their conditions make me confuse.

penpen wrote:One of my PC's is slower and it happens regularly that there are created 2-4 folders for 32 sample files.


But through send to menu it should be ok, yes?

penpen wrote:Added "'s so files/folders with spaces are allowed to move, and the errors should be displayed.


My version is ok with spaces too ;)

penpen
Expert
Posts: 1996
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Group in folder

#13 Post by penpen » 06 Sep 2013 16:53

BijaN-R wrote:I'm new in batch file things.
I know c and java but nested If and for loops of batch files and their conditions make me confuse.
No problem: When i started with batch programming, i had the same problems.
Just break the complex commmands in its parts, or test them standalone to see what they do.

BijaN-R wrote:But through send to menu it should be ok, yes?
Yes, it is ok then: no problem :D .

BijaN-R wrote:My version is ok with spaces too :wink:
Sorry, i have read %~1 although %1 is there... .
I change my post above.

penpen

Post Reply