I'm struggling to get this to work. Plenty of examples on the web, but they all do something just slightly different to what I'm aiming to do, and every time I think I can solve it, I get hit by an error that means nothing to me.
After giving up on the JSLint.VS plugin, I'm attempting to create a batch file that I can call from a Visual Studio build event, or perhaps from cruise control, which will generate JSLint warnings for a project. The final goal is to get a combined js file that I can pass to jslint, using:
cscript jslint.js < tmp.js
which would validate that my scripts are ready to be combined into one file for use in a js minifier, or output a bunch of errors using standard output.
but the js files that would make up tmp.js are likely to be in multiple subfolders in the project, e.g:
D:\_projects\trunk\web\projectname\js\somefile.debug.js
D:\_projects\trunk\web\projectname\js\jquery\plugins\jquery.plugin.js
The ideal solution would be to be able to call a batch file along the lines of:
jslint.bat %ProjectPath%
and this would then combine all the js files within the project into one temp js file. This way I would have flexibility in which project was being passed to the batch file.
I've been trying to make this work with copy, xcopy, type, and echo, and using a for do loop, with dir /s etc, to make it do what I want, but whatever I try I get an error.
You could create a batch file with the following contents:
#echo off
pushd "%~1"
for /r %%x in (*.js) do (
type "%%~x"
)
popd
and then run it via:
jslint.bat PATH > tmp.js
If you don't want to use redirection, you can try:
#echo off
pushd "%~1"
echo.>tmp.js
for /r %%x in (*.js) do (
copy tmp.js + "%%~x" tmp.js > NUL
)
popd
note that for simplicity, I haven't bothered doing any error-checking (e.g. checking whether an argument is supplied (although if one isn't, it'll just use the current directory), testing that tmp.js doesn't already exist, etc.).
A great place for tips on batch files is DosTips.com
Have a look at http://nefariousdesigns.co.uk/archive/2010/02/website-builds-using-make/
The post is written for Linux world but still you might be able to salvage something out of it.
Related
Most companies I have worked for start new projects with a templated folder structure. Windows will automatically flag empty folders (the icon shown in the file explorer is that of an empty folder) however, folders whose subfolders are also empty will not be flagged (their icon shows a folder containing files). This can create confusion and lead to mistakes during the early stages of a project as it would appear at a glance that some folders have had their content added when they really only contain empty subfolders.
So my question is:
How can I iterate over folders with empty subfolders and "flag" them via the use of a Batch file.
The .bat file would need to search through subfolders to determine if a folder has any real content. If the folder does not have real content then the .bat file would need to flag it (flagging could be done with a change of its icon or filename). This would make it much easier to navigate new projects with large templated folder structures.
I don't need a completed file, I would just like to know how it could be achieved. However, any tips or suggestions on how to achieve this functionality would be more than welcome!
*Edit
Just to clarify I will show an example:
If I create an empty folder called 'Project' it will display with the Empty Folder icon. As shown Below:
Now I will add a new folder to my project folder called 'I am Empty':
The folder 'Project' no longer displays with the Empty Folder icon. It now uses the icon that shows it with content. As shown Below:
What I want is a .bat file that will parse the contents of the 'Project' folder and determine that it only contains the 'I am Empty' folder, which is empty and "flag" that folder (to flag it we could change the icon of the 'Project' folder back to the Empty Folder icon, change the name or "gray it out"). As shown Below:
cd example
for /d %%i in (*) do #dir /b /s /a-d "%%i">nul 2>&1|| #echo "%%i" has no files
give for an additional /r if you want to check subfolders too.
The trick is to list files only (/a-d) in the folder and all subfolders (/s) and if this fails (||) (because there are no files), do something with this folder (just echo here, but rd /s /q or ren is also possible)
Building on the answer given by Stephan and looking at other related stack exchange posts I pieced this solution together and it works well for my needs:
#ECHO OFF
PUSHD "%~dp0"
FOR /f "tokens=* delims=" %%F in ('dir /b/s/ad *') DO (
#dir /s /a-d-s "%%F">nul 2>&1|| ATTRIB +H "%%F"
#dir /s /a-d-s "%%F">nul 2>&1&& ATTRIB -H "%%F"
)
POPD
EXIT
I opted for a solution that did not modify file names. While testing that approach I realized it doesn't create the best user experience.
Instead, running this batch file hides the folders that are effectively empty and if your folder settings allow you to see hidden folders then they appear faded out. It also re-shows hidden files that have new content since the last time the batch file was ran.
For those of you coming to this solution who, like myself, are relatively inexperienced with batch scripting. I will explain what the code does and why (as I understand it).
I don't want to change the batch file for each implementation so I call PUSHD "%~dp0 to set the active directory to the folder containing the batch file (this lets me include the batch file in the folder-structure template, which is copied and pasted for each project)
Since I decided to use the hidden attribute for folder flagging, I needed to modify the FOR loop . FOR loops typically ignore hidden files which becomes troublesome if you need show a file that was previously hidden because it has new content. Running FOR /f "tokens=* delims=" %%F in ('dir /b/s/ad *') DO ()
allows the batch file to loop through all files mainly because of the /f attribute, but check out
this post about looping through hidden folders for more information.
Inside the for loop I am pretty much doing what Stephen suggested in his answer with the added logic to remove the hidden attribute on folders that no longer need it.
The only thing this batch file is lacking, is the ability to auto update on folder modifications or to auto-run on folder open (I hear this might be possible with an .ini file?) however, for my needs it will suffice to rerun the batch file, manually, after making changes to the folder.
Batch scripting is way outside of my comfort zone as far as scripting languages go so please forgive and correct me if I have made any mistakes or if there is a more reliable way to do what I need.
How to create a bat file that will execute a single command on all files with a particular extension.
I look for something like this which is there is linux for windows batch files
command *.extension
or even a way to loop through the file with extension would do.
If your command changes the filename and uses the same extension then this solution has a bug, and some files are processed more than once. There are ways around that.
#echo off
for %%a in (*.ext) do (
echo "%%a"
)
Note: There is no need to use batch per say, but I am just familiar with batch, Powershell would be better I imagine, so if there are easier solutions for this problem in powershell, please shout!
I have the arduous task of testing our DR backups for all our clients, that is, mounting ShadowProtect Snapshots latest incremental, writing and reading a file, them unmounting the image. The actual ShadowProtect part of batch is fairly simple but I would like to design a batch that can automate this.
Essentially my question is:
How in a batch file can I firstly, enumerate files in a folder, and then place a specific part of a given filename into a variable?
Reason being ShadowProtect incrementals have a naming convention such like:
SERVERNAME_DRIVELETTER_b00X_i000x - whereby b = base image, i = incremental number
I need to mount the latest incremental image, therefore need to parse the folder and find the latest incremental image, based on the number following the i in the filename.
Is this possible in batch?
Thanks!
Something like this should work:
#echo off
setlocal EnableDelayedExpansion
for /f "delims=_ tokens=1-4" %%f in ('dir /b *_*_*_*') do (
set servername=%%f
set driveletter=%%g
set base_image=%%h
set increment=%%i
)
echo !servername!
echo !driveletter!
echo !base_image!
echo !increment!
endlocal
If you have several matching files and want to do something with all of them, you need to put the processing code inside the loop.
Edit:
for /f: process either a file or the output of a command enclosed in single quotes
delims=_: fields in the processed content are separated by underscores
tokens=1-4: assign the first four tokens to the parameters %%f through %%i (first parameter is the one given in the for statement)
dir /b *_*_*_*: list all file where the name contains at least 3 underscores with just their file name (the output of this command is processed by the for loop)
setlocal EnableDelayedExpansion: expand variables at run time (otherwise assigning the parameters to variables wouldn't work)
For further details see help for and help dir.
You could always use vbscript or jscript. It is much more powerful than batch files. Also jscript and vbscript hosts are available also on machines that don't have powershell!
Link for enumeration:
http://www.techimo.com/forum/webmastering-programming/100453-recursive-javascript-list-all-files-folders-given-folder.html
Jscript string reference:
http://msdn.microsoft.com/en-us/library/bxsyt3yc(v=vs.80).aspx
You should be able to combine the two.
you run your jscript (I prefer jscript to vbscript because of its resemblance to javascript)
cscript scriptname
I have a list of files in a folder that end with .swf.
I want to change all those files from X.swf to X<some number>.swf.
How can I do that?
This little script will change all *.swf files into the equivalent *_42.swf files.
#setlocal enableextensions enabledelayedexpansion
#echo off
for /f %%a in ('dir /b *.swf') do (
set fspec=%%a
set newfspec=!fspec:~0,-4!_42.swf
echo ren !fspec! !newfspec!
)
endlocal
Actually, as it stands now, it will just echo the commands that it wants to execute. Once you're happy they're correct, you can just remove the echo from that renaming line above.
It works by using for /f to get a list of all SWF files and then using string manipulation to:
remove the last four characters (the.swf extension); then
add a new _42.swf extension onto the end.
And, please, make sure you back them up first :-)
You could use the following one-liner directly from the command prompt:
FOR %F IN (*.swf) DO RENAME "%F" "%~nF123.*"
where 123 stands for your number of choice.
Alternatively you could create a batch file and take advantage of its ability to accept parameters. Use the following script:
#ECHO OFF
SET "suffix=%~1"
FOR %%F IN (*.swf) DO RENAME "%%F" "%%~nF%suffix%.*"
Now if the batch's name is renamer.bat, you can invoke it like this:
renamer.bat 2011
and it will add 2011 to the name of every .swf file in the current directory.
Assuming <X> in your description is supposed to be constant and you don't explicitly require a batch script to solve your problem, you can use Windows Explorer as mentioned in an article by Microsoft titled "Rename a file".
Here's a an extract from said article:
"You can also rename several files at one time, which is useful for grouping related items. To do this, select the files [then press F2]. Type one name, and then each of the files will be saved with the new name and a different sequential number at the end (for example, Renamed File (2), Renamed File (3), and so on)."
I wrote a small batch file to rar all contents in all subfolders within a folder. It works fine except for that the file names should be in ASCII. Below is the working small code:
#REM ------- BEGIN rarthem.bat ----------------
#setlocal
#echo off
echo --------------------------------------------------
echo Starting to rar files
echo --------------------------------------------------
echo.
echo.
echo.
set path="C:\Program Files\WinRAR\";%path%
for /D /r %%G in ("*") do (
echo Storing files in %%G
echo --------------------------------------------------
cd %%G
for %%I in (*.*) do (
rar a -x*.rar -x*.zip -m0 -id[c] "%%~nI.rar" "%%I"
echo Done archiving %%~nI%%~xI
)
echo --------------------------------------------------
echo Done archiving %%~nG
echo --------------------------------------------------
echo.
echo.
cd ..
)
echo Finished!
pause
REM ------- END rarthem.bat ------------------
I think the problem happens when the file name is parsed to WinRAR as WinRAR has no problem archiving files with Unicode names.
Edit: When parsing the file name to WinRAR, the file name gets modified so when WinRAR tries to look for the file under that name, it can't find it. For example a file: téxt.pdf will become text.pdf when parsed.
A small side question: I've not tried using 7zip, would it be easier to achieve the same thing with 7zip?
Many thanks for help.
RAR.exe processes its command-line in the OEM character set (i.e. not unicode). The only way I know of to pass a unicode name to it is via a list file, when also using the argument to specify that the list file is unicode. However, that only works for files inside the archive (EDIT: or files you want to add to the archive). For the archive name itself I don't know of a solution except...
If you use WinRAR.exe instead of RAR.exe then you can pass unicode filenames on the command-line and they work fine. You will see a GUI progress window but other than that (which may or may not matter to you) WinRAR.exe is suitable for running from batch scripts.
Whether a batch script itself can cope with unicode I do not know, but if that is the only problem remaining I would switch to using VBScript or JScript instead of a batch file. (Which is worth doing anyway, IMO. I'm not a big fan of VBScript and JScript but at least they don't have completely insane, arcane semantics and limitations like batch does. :))
By the way, if you do use WinRAR.exe you might want to get the recent WinRAR 4 (beta 2 currently) as it includes the ability to specify the working directory, previously only possible with rar.exe. That can be essential if you need to add files from read-only directories.
If you want to learn about the list files I mentioned, check the RAR.exe text-file document or the WinRAR.exe built-in online help for all the details.
Hope that helps!