I need to map a directory into it's own drive, (i know it's achivable using windows tools like "Map network drive", "subst"), but using these tools, the mapped drives aren't MVFS anymore...
I'm looking for a way to map MVFS folders in some dynamic view to it's own drive, or alternativly, configure a config spec to filter everything except a specific folder, for example, configure a config spec so that:
M:\some_dynamic_view\some_folder\some_nested_folder
would be mapped to :
K:\some_nested_folder
Any ideas?
Thanks in advance,
Erik.
(The need to map folders into drives is because of the clearcase path length limitation on windows).
I just tested:
subst N: M:\some_dynamic_view\some_folder\some_nested_folder
and N: would display the content of some_nested_folder, as a dynamic view would.
Its type is a MVFS filesystem drive (named CCase by default)
Now, to have only the directory (and not directly its content) in N:\, you would need a config spec like:
element /some_folder/some_nested_folder/... /main/LATEST
element /some_folder/* -none
element * /main/LATEST
(supposing a simple non-UCM view, with only the main branch to see. Adapt the config spec to your configuration and branch on which you need to read/modify files.
For a UCM view, that would be trickier, since those rules would have to be place before all the other generated UCM selection rules, meaning they would disappear at the next view config spec synchronization with its stream.)
(note: no need to use '\' in config spec, '/' works just fine, for Windows or Unix config spec)
Then, a:
subst N: M:\some_dynamic_view\some_folder
would only display some_nested_folder (and its content) in N:
I mainly use snapshot views so I don't think I can use the m:\path_to_view solution. After many years of shouting "doh" at my monitor I wrote this batch file to save me having to change directory back to the original location of the view every time I wanted to run a cleartool command.
#echo off
rem ct.bat by Paul Douglas
setlocal
setlocal enabledelayedexpansion
set currentDirectory=%cd:~2,8189%
set currentDrive=%cd:~0,1%
for /f "delims=" %%a in ('subst') do (
set thisDrive=%%a
set thisDrive=!thisDrive:~0,1!
set targetFolder=%%a
set targetFolder=!targetFolder:~8,8183!
if "!thisDrive!"=="%currentDrive%" (
pushd !targetFolder!%currentDirectory%
call cleartool %1 %2 %3 %4 %5 %6 %7 %8 %9
popd
goto :eof
)
)
call cleartool %1 %2 %3 %4 %5 %6 %7 %8 %9
Related
I have a quantity of folders with archive files,
Parent folder with subfolder eg
Graphics:
graphics 01012021/file31241.7z
graphics 01022021/file4231.7z
odds and ends 01032022/filejohnny.7z
etc
each folder contains an archive - various names numbers.
each archives contains various files, pdf's txt files invoices and image files.
Generally the images are .jpg named various names.
What I would like to do is batch attack the parent folder to extract an image file/s from the each archive from each sub directory and leave the image in the subdirectory with the archive where it came from. If the archive has multiple images that's fine, I am not targeting a single particular image.
hopefully ending up with something like
Graphics:
graphics 01012021/
file31241.7z
yellowstone.jpg
flintstone.jpg
graphics 01022021/
file4231.7z
martha.jpg
odds and ends 01032022/
filejohnny.7z
artemis.jpg
French toast.png
I would rather avoid if possible extracting all the files separating the images then having to re archive.
What I tried to discover originally was to batch extract the image files to the directory it belongs to, have the image file renamed to its directory name. I didn't get close with a solution, so I think if possible just extracting the image would be fine and I can use a renaming app to do the other I've found bulk rename utility to be just fine once I got my head around it.
You wouldn't think that over the years you would collect so many archives, like small drops they ended up become an ocean full.
I have tried researching stack and seen a lot of examples of how eg 7zip works but I just cant get my head quite around it.
I am due to retire they tell me 65 is the time for the chicken coop, I've been a pencil pusher and mouse skater most of my life in the gfx industry. I used to know what was in each archive but memory is a little how to say... rusty nowadays, I know all my archives have images in them. My life would be a lot easier in the sunset of it to look at the pictures and not have to rack my brains trying to remember what was in the archive itself.
Cheers and ty in advance from the colonies downunder.
Grumpy
I found the solution to my issue, no coding just using an app I've been using for years. Total Commander.
Solution was simple in the end.
I open up Total Commander, do a search for the archive files I want Alt F7 it will list in the right hand frame all my archives .7z .zip whatever you have.
Then you select "feed to list box" found in the bottom right hand corner. Do a Ctrl A then Alt F9 which gives you some options.
You clear unpack specific files from archive to "make sure its blank" then files to unpack tell it what your looking for in my case .jpg (it can be any specific file).
Untick unpack path names if stored with files
tick or untick overwrite existing files
untick unpack each archive to a separate subdir (name of the archive)
Hit ok.
It will then search and find the file/s you are looking for and unpack them in the directory/subdirectory/etc they are found in.
Job done... No coding just using TC.. marvellous app
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following settings for the source directory, destination directory, target directory,
rem batch directory, filenames, output filename and temporary filename [if shown] are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "destdir=u:\your results"
SET "outfile=%destdir%\outfile.txt"
SET "extensions=bat txt"
SET "archives=7z zip"
CALL :prefix sdexts *. %extensions%
CALL :prefix sdarchives *. %archives%
CALL :prefix dexts . %extensions%
CALL :prefix darchives . %archives%
PUSHD "%sourcedir%"
(
FOR /f "delims=" %%b IN ('dir /b /s /a-d %sdexts% %sdarchives%') DO (
SET "unreported=%%b"
FOR %%o IN (%darchives%) DO IF /i "%%~xb"=="%%o" CALL :procarch%%o&SET "unreported="
IF DEFINED unreported ECHO %%~dpb ^| %%~nxb
)
)>"%outfile%"
popd
GOTO :EOF
:: return %1 with each other argument preceded by '%2'
:prefix
SET "$1=%1="
shift
SET "$2=%~1"
:sdl
SHIFT
IF "%1"=="" SET "%$1%"&GOTO :eof
SET "$1=%$1% %$2%%1"
GOTO sdl
:: Process .7z or .zip archives
:procarch.7z
:procarch.zip
SET "skipme=Y"
FOR /f "delims=" %%e IN ('7z L "%unreported%"') DO (
FOR /f "tokens=3delims= " %%o IN ("%%e") DO (
IF "%%o"=="------------" (
IF DEFINED skipme (SET "skipme=") ELSE (SET "skipme=Y")
) ELSE IF NOT DEFINED skipme ECHO "%%o"|FIND "D" >NUL &IF ERRORLEVEL 1 (
SET "filename=%%e"
FOR /f "delims=" %%y IN ("!filename:~53!") DO (
FOR %%c IN (%dexts%) DO IF /i "%%c"=="%%~xy" ECHO %unreported% ^| %%y
)
)
)
)
GOTO :eof
I've a similar requirement, so I spent a bit of time on this...
The first part simply sets the directories to be used.
I used bat and txt as extensions required for testing. Change as desired - just a space-separated list.
Similarly, I chose to examine .zip and .7z archives. Since 7zip can deal with both, the same subroutine can be used to process both. Other archive types may need different processing.
The code uses dir to locate the files of interest, and dir can take a series of arguments, so the routine :prefix converts the list provided as %3+ to a list in variable %1, each term prefixed by the string at %2.
So - sdexts will become *.bat *.txt and dexts .bat .txt for instance.
Next, switch to the source dir to begin the dir to list the required files. For each name returned in %%b (delims= applies the full name, /b basic list (names only), /s processes subdirectories, /a-d suppresses directorynames) - the flag unreported is set to the filename found then the extension of the filename found is compared to the darchives list. If a match is found, execute the procarch%%o routine is executed and the unreported flag set to empty. Then, if unreported has not been cleared, it's not an archive file, so report it.
procarch%%o will be resolved either procarch.7z or procarch.zip and a routine (actually the same routine) is provided.
The :prefix routine sets $1 to %1=, so for example, sdexts=. Then it shifts the parameter list and sets $2 to the prefix to be placed before each term.
Then shift again. If %1 is not empty, append a space and the prefix in $2 and %1 to $1 and repeat.
When %1 becomes empty, execute the command set "%$1%" and finish, so as $1would then contain the stringsdexts= *.bat *.txt, sdexts` would be set to the list required.
The routine :procarch.7z or procarch.zip (the first simply falls through to the second, so the same processing is executed) sets the flag skipme to non-empty as we need to skip 7z's header data.
%%e acquires each line of the 7z L report in turn. %%o is assigned the third token of the 7z report line. This will be junk up to the line with a series of dashes, then the attribute report for the archived items, then another series of dashes, then junk.
So - if %%o is a string of dashes, simply switch skipme to empty/not empty.
If %%o is not dashes, and skipme is not defined then we are between the two lines of dashes (ie. on an archived item line) so we see whether %%o contains D (which would indicate that this is a directory name, which we do not want to report). If it does not, errorlevel will be set non-zero by the find (output of the find is sent to nul=the æther) filename set to the full report line. We're not interested in the first 54 characters, but the remainder contains the archived filename, so see whether the extension of the filename found is one of interest (in dexts) and if it is, report it.
The ( on the line preceding the for ... %%b matches the )>"%outfile%" and sends all output that would otherwise go to the console to the file named.
And the ^| on the echo lines output a literal | character as | is a special character for cmd and needs to be escaped by ^ to be interpreted as a literal.
To answer your question the task is simple involving For loops with recursion, however to be robust the solution will be complex without knowing how those specific long term possibly mixed, 7zip files are subdivided, thus if a 7zip has itself two sub folders with identical named files you will hit error conditions. I have allowed for that using -aou to auto rename if necessary. however I have not added the folder name to each file as that's an extra step.
#echo off & Title Extract Images from 7z files
set "extractor=C:\Program Files (x86)\7-Zip\7z.exe"
set "archives=*.7z"
set "filetypes=*.png *.jpg *.jpeg *.tif *.tiff"
set "startDir=C:\Users\WDAGUtilityAccount\Desktop"
FOR /R "%startdir%" %%I IN (%archives%) DO ( "%extractor%" e "%%I" -o"%%~dpI" %filetypes% -aou)
You can add extra archive types such as .rar or .zip in the same way I have allowed for different image file types. HOWEVER do test for such variations first otherwise a second run will invoke that autonaming of existing duplicates. You can of course change that -aou to -aos to avoid overwite or remove it as desired.
An alternative approach on windows is that, standard windows.zip files can be navigated and thus kept as compressed folders where a click on each file will open in the default application. Thus only need extraction to the folder when you wish to use a non default app.
The secondary advantage more directly related to your need is that some viewers can read just the images and ignore any other contents (even if they can read text or html) and one I support that reads images in zips is SumatraPDF and although not listed it can open .7Z files to show in the same way
Hence my answer to the posed question is I suggest converting 7zip to standard zip rather than expand them, or use SumatraPDF as default/alternative 7z viewer !!.
I am trying to create an active setup to copy files to all users profile after application launch.
Using this command, I am unable to copy file(s) to user profile
The problem is that although no one uses profiles, the "Default" Profile have a random prefix name (24xwe234.default \ 45qw324w.default).
xcopy "C:\Temp\123.cfg" C:\users\%username%\AppData\Roaming\Mozilla\Firefox\Profiles\*.default" /d /y
How can I copy the file to the ****.default/ Folder via batch script?
If you have Administrative privileges (in order to read/write other users %HOMEPATH%), then everything below could be applied to other users, else it's limited to your own user only.
Although xcopy is a pretty advanced command, I don't think it can handle wildcards at destination in this scenario (also didn't you miss an "*" after ".default"?).
One alternative would be to use a .bat script that iterates (using [SS64]: FOR /F (or [MS.Docs]: for)) over the .default* like dirs (corresponding to Firefox profiles - not an expert on this area, could there be more than 1?) and copies the file (using good old [MS.Docs]: copy) in each of them (if any).
code.bat:
#echo off
setlocal enableextensions
set _SOURCE_FILE="C:\Temp\123.cfg"
set _TARGET_USER=%USERNAME%
set _FIREFOX_PROFILES_PATH="C:\Users\%_TARGET_USER%\AppData\Roaming\Mozilla\Firefox\Profiles"
for /f %%f in ('dir /b "%_FIREFOX_PROFILES_PATH:"=%\*.default*"') do (
echo Copying %_SOURCE_FILE% to "%_FIREFOX_PROFILES_PATH:"=%\%%f"
copy /y %_SOURCE_FILE% "%_FIREFOX_PROFILES_PATH:"=%\%%f"
)
As it is now, the script copies the file in the default Firefox dir(s) for current user only.
Again, with Administrative privileges, it can be extended to iterate all existing users, and do the same thing for each of them (well, it could be extended anyway, but it will still do only what's doing now, when run by a regular user).
But anyway, the question (or, at least the step that posed problems) is about the current user's .default profile.
I created a .bat file to replace 3 files from a DVD burned into a directory on my PC, the directory in all others the path is fixed, however it has a complication in case of my driver cd player and dvd the letter is j. But in other drivers when inserted the dvd of course the letter will change to f or g or i for example, how to solve this? How exists? because the Type the folder where it will be copied this defined in problem, but how to get and copy all files of this folder specify in or add variants and search type let's assume that the driver is with the letter n as I put in bat to find this folder with those Files and paste inside the folder that I specified? Is it possible?
I have the following .bat: copy j:\dvd folder\*.* "c:\file of destination in the pc. This .bat file recognizes the drive J as if it were in any other PC in a universal way let's say, regardless of which PC the bat is fired it will go into that DVD folder will copy and paste in the specified folder in c: windows windows folder Is not the problem, the problem is fixed the problem is this other unit of dvd in which the letters of the unit change from there will not work when clicking this bat because it is in my pc for example in another it will be i, this is the problem.
You may be able to leverage the WMI command line:
#Echo Off
Set "CDROM="
For /F "Skip=1 Delims=" %%A In (
'"WMIC CDROM Where (MediaLoaded='TRUE') Get Drive 2>NUL"'
) Do For %%B In (%%A) Do If Exist "%CDROM%\DVD Folder\" Set "CDROM=%%B"
If Not Defined CDROM GoTo :EOF
Copy "%CDROM%\DVD Folder\*.*" "%SystemDrive%\Somewhere Existing"
Timeout -1
Think from another perspective.
#echo off
copy "%~Dp0Dvd Folder\*.*" "C:\Folder\"
rem We don't need \ in between %~Dp0 and Dvd Folder because %~Dp0 comes with a \
Place this batch file in your DVD root folder.
Explanation:
%~Dp0
In a batch file, can I copy a folder located by a constant path like \\?\Volume{GUID}?
When copying (copy, xcopy or robocopy) a directory and its content from a local removable drive (a usb external drive for instance) to another location on the same drive, I'd like to use unique and constant absolute paths like \\?\Volume{GUID} to avoid using drive letters that can change over time.
To operate the copy, the batch file is meant to be placed on the removable device, but in case the file is moved or placed somewhere else I'd rather be sure it's operating on the good drive.
So far I've tried:
COPY can handle \\?\Volume{GUID} paths to copy a file but cannot copy
folders
XCOPY returns an "invalid drive" error
ROBOCOPY gives a "network path not found, wait 30 sec..."
for each command above : syntax variations with \\?\UNC\Volume{guid} and with the trailing "\"
Am I doing something wrong or is this just not the way to do that?
Is there another way to use invariant locations?
Ideally it should involve the least tweaking possible. By tweaking I mean: labeling the drive or giving it a fixed letter, etc.
Have a look at pushd /? and popd /?
pushd \\?\UNC\Volume{guid}
will short time map the UNC path as a network drive and change the directory to it according to the next free drive of your computer from the end of the alphabet.
For example, you got Z:\ and Y:\ already it will map the path to X:\ and change the current directory to X:\.
From that on you can go for copy filefromServer.foo C:\localfile.bar
The other commands such as XCopy can use the mapped drive as well.
To unmap the drive use popd.
None of the copy function can work with unc path.
Thus the only way is a workaround that consists in retrieving the drive letter through wmic command.
Here's the code :
for /F "usebackq tokens=1,2 delims==" %%G in (`
wmic volume where "DeviceID='%_volID:\=\\%'" get DriveLetter /value
`) do set _%%G=%%H
with _volID being the variable containing the unc path of the volume in question
I've gotten excellent help here recently, which I keenly appreciate. Thanks to the breadth of knowledge on this site I've been able to cobble together some code which is trivial in its purpose, yet important for my environment.
The simplified purpose, and my problem:
The goal: for the current user, upon login to Windows, move all files and folders into a desktop folder named "Archive" [create the latter if necessary]. (The content moved is put into a dynamically created subfolder based on timestamp.)
The existing problem: the code fails to move desktop folders into the (deskstop) Archive folder. (I obviously don't want to move the Archive folder itself.)
Any insight / solution would be hugely helpful. (PS if at all possible I wish to keep to DOS bat files vs more complex languages.)
My current .BAT file [note- the many variables are for initial debugging]:
++++++++++++++++++++++++++++
:: Establish desired base name for the primary desktop archive folder
set ARCH=Archives
:: Establish logged in user path to desktop
set G=%USERPROFILE%\Desktop
:: Now, if "Archives" folder does not yet exist on desktop, create it
if not exist "%G%\Archives" mkdir "%G%\%ARCH%
:: Consolidate pathname <user\desktop\Archives> into single variable (TARGET)
set TARGET=%G%\%ARCH%
:: Create [date+time specific] subfolder name -- two steps - build string, then assign
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%" & set "MS=%dt:~15,3%"
:: Set variable to hold new name Archives\Saved-<time-specific-subfolder> in final form
set "savedirname=Saved-%YYYY%-%MM%-%DD%-%HH%-%Min%-%Sec%"
:: Finally, append new foldername to user-specfic path (TARGET)
set MoveTo=%TARGET%\%savedirname%
:: Create final targeted destination folder - complete pathname
mkdir %MoveTo%
:: Move all desktop files/folders EXCEPT the Archives folder into the targeted destination
for %%i in (%G%\*.*) do move %%i %MoveTo%
Thank you!
(PS if at all possible I wish to keep to DOS bat files vs more complex languages.)
This isn't the answer you ask for, but this is PowerShell (v4) code to do what your code does:
$arch = "Archives"
$desktop = [Environment]::GetFolderPath("Desktop")
$saveDirName = Get-Date -f "yyyy-MM-dd-hh-mm-ss"
$target = "$desktop\$arch\$saveDirName"
mkdir $target -Force
dir $desktop | where Name -ne $arch | Move-Item -Destination $target -Force
Is it really "more complex" than your original code?
Your original code guesses that %USERPROFILE%\Desktop is the desktop - that's incorrect if the desktop is redirected, it could be \\fileserver\users\username\desktop\. It's incorrect if the OS is installed in a foreign language, in Swedish it's %UserProfile%\Skrivbord. Asking Windows where the desktop is gets the correct location every time. My code does this.
PowerShell handles dates sanely. No string manipulation, no WMI calls, one formatting string for what format you want.
I use the mkdir -Force option, it can make folders two levels deep in one go, and it does nothing if they already exist. No need for IF NOT EXIST... tests, although you could do them with Test-Path. You could use this approach in the batch file, mkdir can make multiple nested folders there, too.
NB. your code has a bug where you check for "%G%\Archives" but you mkdir "%G%\%ARCH%. If %ARCH% is meant to be configurable, they could differ.
And this version does the folder moving which you are asking about that your code doesn't yet do, and will need another abuse of a for loop to handle.
This script is half the amount of code, more readable because it directly does what it needs instead of wandering out to wmi and string manipulation and for loops for string handling, it's more correct in more situations, more resilient, and does the extra things your original doesn't.
Yes it's a bigger and more complex language - that's how it makes things easier for you, because it can do more things directly.
set fldr="%userprofile%\desktop\archive\%date:/=%%time::=%"
md %fldr%
For /f "delims=" %A in ('dir /a-d /b "%userprofile%\desktop" ^| Findstr /I /v /c:"archive"') Do #echo move "%userprofile%\desktop\%A" %fldr%
The above is all you need.
Batch isn't a programming language, although IBM engineers added programming like features.
It designed for copying files and starting programs. It becomes a stupid language if used as a programming language.
Use %%A in a batchfile. Remove Echo to have it actually move files.
To get the doc folder, which is always called desktop (explorer substitutes localised names for real names via the desktop.ini file)
for /f "skip=2 tokens=3" %A in ('Reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v "Personal"') do set doc=%A
Use %%A in a batchfile.