Batch script to pngcrush all files in all subfolders - image

I have a folder structure with one main parent folder containing many subfolders, and in these some PNGs, something like:
.../data
.../data/013523/
.../data/345343/
.../data/395338/
.../data/013523/filex.png
.../data/013523/filey.png
.../data/345343/filea.png
.../data/345343/fileb.png
.../data/345343/filec.png
I'd like to crush all these PNGs with a Windows batch-script knowing only the location of the parent data folder (ie the folder names and png names are unknown, it should just crush all PNGs in all folders).
I took a look at Drag and drop batch file for multiple files? but this didn't seem to be quite what I was after.
Oh and no fancy naming options required, crushing in-place is fine.

Well
for /r ...\data %%x in (*.png) do pngcrush "%%x"
should do it.
If the path to your data directory contains spaces somewhere, the following should work better, though:
pushd "...\data"
for /r %%x in (*.png) do pngcrush "%%x"
popd

Related

Copy files matching string(s) in a text file out of many subfolders with folder structure to another destination folder

I have a lot of image files in a folder structure like this:
/Foldername1 (hohe Auflösung)/PictureRANDOMNAME1-FB.jpg
/Foldername1 (hohe Auflösung)/PictureRANDOMNAME2-FB.jpg
[...]
/Foldername2 (hohe Auflösung)/PictureRANDOMNAME1-SW.jpg
/Foldername2 (hohe Auflösung)/PictureRANDOMNAME2-SW.jpg
[...]
/Foldername3 (hohe Auflösung)/PictureRANDOMNAME1-SP.jpg
/Foldername3 (hohe Auflösung)/PictureRANDOMNAME2-SP.jpg
[...]
Now I have a filelist.txt with a list of some of these image files, like this:
PictureRANDOMNAME1, PictureRANDOMNAME3, [...]
I would like to copy all images matching the string(s) in the text file list out of all subfolders to a new destination (not moving them) while keeping the folder structure.
Maybe I need a batch file that I just copy into the main folder with all the subfolders, together with a filelist.txt, execute it and get the same folder structure but only with the wanted files on another destination.
Special about this might be the spaces in the paths and the umlauts.
Sorry for my bad english. I honestly tried my best. Maybe some native speaker could help editing to be more understandable.
#echo off
setlocal
:: This copies the tree structure from sourcedir to destdir
xcopy /t /e sourcedir destdir
:: This reads the filenames and copies the required files
for /f "delims=" %%a in (filelist.txt) do (
for %%b in (%%a) do xcopy /s /e sourcedir\%%b* destdir
)
%%a acquires the lines from the file. Since each line is comma-separated, %%b will execute xcopy on each name on the line.
You could add >nul to the end of the xcopy lines to suppress reporting if you like.
Please note that / indicates a switch in winbatch - \ is the directory-separator.
This procedure is untested. I suggest you try it against a small dummy subdirectory tree to verify it before relying on it for your live data.

Windows CMD or BATCH file that "flags" empty folders (and folders that only contain empty folders)

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.

Extracting files out of a huge directory

I have a folder that is filled with:
.mp3 files
Folders that contain mp3 files Folders that contain some
amount of folders.
Each sub-directory may or may not have mp3 files.
I need to extract only the mp3 files out of it and save them elsewhere. The problem is that 90% of the mp3 files have spaces in them. So running this particular script does not work:
pushd C:\Users\XXX\Desktop\UNSORTED_MUSIC
for /r %%a in (*.mp3) do copy %%a C:\Users\XXX\Desktop\YEAH\"%%~nxa" /y
It moves space-less files just fine. But otherwise, it skips the rest. How can I modify my script to work?
for /r %%a in (*.mp3) do copy "%%a" C:\Users\XXX\Desktop\YEAH\"%%~nxa" /y
Simply quote any string that may contain separators like spaces.

Directing files in different folders through couple programs with .bat

Basically, I'm trying to batch-compress .png images which are residing in various folders. For that, I use pngquant and pngout. Every image should go through these apps this way:
pngquant.exe --force --speed 1 --verbose image.png -o step1.png
pngout.exe step1.png step2.png
I want all images compressed at once. To gather a list of all images in folders, I search with *.png query in root folder. The aim is to just throw all images to batch file and wait for the result.
I looked around a bit and come up with this
for %%i in (*.png) do (
"...\pngquant.exe" --force --speed 1 --verbose "%%~ni.png" -o "%%~ni2.png"
"...\pngout.exe" "%%~ni2.png" "%%~ni3.png" )
So I'm dragging the images onto the .bat file, but only the images from the first folder would go through, the batch file ignores images from the subsequent folders. How can I fix that? Thanks.
for /f "tokens=*" %%i in ('dir *.png /s /b') do (
"pngquant.exe" --force --speed 1 --verbose "%%i" -o "%%~di%%~pi%%~ni2.png"
"pngout.exe" "%%~di%%~pi%%~ni2.png" "%%~di%%~pi%%~ni3.png" )
try this. but note that PNGs will be created in the same folders. don't know however if it was your intent.
Dropping files on the batch file is the same as providing them as arguments on the command line. Your script ignores its arguments and processes just its working directory.
Replace the for argument (*.png) with (%*), which contains the list of all arguments.
Also, instead of %%~ni, which returns just the name of the file, you'll need to say %%~dpni, to include the drive and path, if the files are not in the same folder as the script.

Windows batch copy files from subfolders to one folder

I had tried to make batch script that copies all *.tif files located in D:\images(random named subfolders here) to d:\all.
xcopy D:\Downloads\*.TIF D:\temp\ /s
works, but it copies with all folder tree. I tried to use other keys, but its dont works.
Thanks for help!
FOR is your friend. Read HELP FOR on the /R option and the %~nx variable substitution; and then try this very simple code.
pushd d:\downloads
for /r %%a in (*.tif) do (
echo COPY "%%a" "d:\temp\%%~nxa"
)
popd
watch carefully the results and then remove the ECHO command.
You will have to refine the code to cope with errors, duplicate names, edge cases, names with reserved characters, race conditions, cosmic events...
Searched files using windows file explorer for e.g. *.gif , I got files in search window, used Edit=>Select All , copy and then pasted to desired folder. This copied all the gif files in all sub directories to single folder.
For large number of files, it sometimes hangs/not responding, but otherwise works ok.
pushd D:\Source
for /r %%a in (*.?*) do (
MOVE "%%a" "D:\Destination folder\%%~nxa"
)
popd
You can also use the XXCOPY freeware. Works like XCOPY, but when you use a /SG parameter, it flattens the sub-directories. See how to use it here.

Resources