Here's what I have;
On a windows-based web server there are roughly 1,000 zip files, each with dozens of log files inside. I already have a script that goes through each archive and deletes all but one specific file type (in an attempt to save diskspace and delete things I don't need). Then, the script unzips each archive to their own folder. And I know how to code the reverse of that to zip them back when I'm done.
Here's what I need to figure out;
Once I run the previously mentioned script (we call it garbageman because it cleans out the garbage in the zip files) I need to go through the remaining 5 or 6 files in each of the newly created unzipped folders, and look for a specific string in each file. If I find the string, I delete everything that is not that string, and save it to a file called "export.txt" in that folder. Then, I move to the next unzipped file, and so on. Once completed, I need re-zip everything back together into their own archives
Here's what I have for code so far. Any help is extremely appreciated.
cd "C:\Program Files\7-Zip"
FOR %%c in (C:\Users\xxxxxx\Desktop\LogQueue\*.*) DO 7z d %%c "-x!xstore*" -r
FOR /R "C:\Users\xxxxxx\Desktop\LogQueue" %%I in ("*.zip") do (
"%ProgramFiles%\7-Zip\7z.exe" x -y -o"%%~dpnI" "%%~fI"
)
cd "C:\Users\xxxxxxx\Desktop\LogQueue"
FOR /R "C:\Users\xxxxxx\Desktop\LogQueue" %%I in ("*.*") do (
findstr "xxxxxxxx_eReceipt" %%~fI > %%~dpnI\export.txt
pause
)
for /d %%X in (*) do "c:\Program Files\7-Zip\7z.exe" a "%%X.zip" "%%X\"
This is an edit:
This script should do what you want.
Only Change sourcedir and mystring variables.
export.txt will be inside a file called Storage in the root directory of the batch.
:ScriptA
#ECHO ON
MKDIR "%CD%\Storage"
MKDIR "%USERPROFILE%\Desktop\Outx"
GOTO :ScriptB
:ScriptB
::REM ONLY CHANGE
SET "sourcedir=%USERPROFILE%\Desktop\Test"
FOR /R "%sourcedir%\" %%a in (*.txt) do copy "%%a" "%CD%\Storage"
:ScriptC
:ScriptC
#ECHO OFF
SETLOCAL
SET "VARA=%CD%\Storage"
SET "VARB=%USERPROFILE%\Desktop\Out"
::REM ONLY CHANGE
SET "mystring=PUT_STRING_HERE"
FOR %%a IN ("%VARA%\*.txt") DO FINDSTR "%mystring%" "%%a">nul&IF NOT ERRORLEVEL 1 FINDSTR "%mystring%" "%%a">"%VARB%\%%~nxa"
DEL /F "%CD%\Storage\*.txt"
GOTO :ScriptD
:ScriptD
#ECHO ON
COPY /B "%USERPROFILE%\Desktop\Outx\*.txt" "%CD%\Storage\export.txt"
RD /S /Q "%USERPROFILE%\Desktop\Outx"
goto :eof
Related
I have a huge folder that I would like to transform into several small ones of 20 files each and compressed. I would like to do this automatically with a batch file and 7zip.
To achieve this I thought about 2 steps:
1. Create a sub-folder for each 20 files (source) :
#echo off
set /a counter=1
set /a filesperfolder=20
cd "C:\Users\Desktop\dir\"
:loopstart
set dirname=dir_%counter%
md %dirname%
echo %dirname%
dir /b | findstr /v /i "dir_*"> %temp%\temp.txt && for /l %%l in (1,1,%filesperfolder%) do #for /f "tokens=1,2* delims=:" %%a in ('findstr /n /r "^" %temp%\temp.txt ^| findstr /r "^%%l:"') do #move %%b %dirname%\%%b >nul
set /a counter=%counter%+1
for /f "tokens=*" %%a in ('type %temp%\temp.txt ^| find /c /v ""') do set _filesmoved=%%a
del %temp%\temp.txt
IF %_filesmoved% LSS 20 goto done
goto loopstart
:done
cls
echo All files were moved!!
pause
exit
Unfortunately this does not work : The syntax of the command is incorrect.. I've tried debugging the script by removing the #echo off and it tells me that the dir /b | findstr /v /i "dir_*"> %temp%\temp.txt && for /l %%l in (1,1,%filesperfolder%) do #for /f "tokens=1,2* delims=:" %%a in ('findstr /n /r "^" %temp%\temp.txt ^| findstr /r "^%%l:"') do #move %%b %dirname%\%%b >nul part is not working (same error). This part is quite fuzzy for me and a little help would be welcome.
I specify that the file temp.txt contains my complete list of files, without any separator (one file per line).
--- UPDATE: filenames must not contain spaces ---
2. Compress all these subfolders one by one with (source) :
for /D %d in (*.*) do 7z a -tzip "%d.zip" ".\%d\*"
Do you have an idea for (I summarize) : create, for a large number of files, subfolders of 20 files in order to compress each subfolder one by one.
If you have any idea on how to compress each 20 files directly (without going through the creation of subfolders) I also agree!
Thank you in advance for your help!
Resolved!
I found my mistake. In reality my files included spaces that the script could not fit.
So, to answer my basic question which was: in a big folder filled with thousands of files, how to compress each 20 files in subfolders? it is necessary (to my knowledge) to:
Create a sub-folder for each 20 files whose name does not have spaces (code in my question)
Compress all these subfolders one by one (code in my question)
And it's done!
Do not hesitate to suggest a solution if you know of a "faster" one.
No need to create folders. Just iterate over the files and add every single file to it's designated zip file (instead of copying every 20 files into a folder and zip that folder)
Use two counters to keep track of (source)files and zip files. One counter for the files (use the Modulo-operator to check for each 20) and one for the zip filenames. I started the zip filenames with 10001 instead of 1 and took the last four chars of it to get sortable file names (0001.zip etc).
#echo off
setlocal enabledelayedexpansion
set filesperfolder=20
cd /d "%cd%"
set "zipDest=C:\temp"
set filecounter=0
set foldercounter=10001
for %%a in (*) do (
set /a filecounter+=1
set /a check=filecounter %% filesperfolder
if !check! == 0 set /a foldercounter+=1
ECHO 7z a -tzip "%zipDest%\!foldercounter:~-4!.zip" "%%a"
)
Obviously adapt the cd /d line (source folder), destination folder (Attention: don't use the source folder, or your zip files might be zipped again into other zip files), and maybe the zip-filename (like "%zipDest%\MyZips-!foldercounter:~-4!.zip")
NOTE: I disarmed the 7zip command with ECHO for testing and troubleshooting. Remove the ECHO when the output satisfies you.
To delete each file after successfully zipping them, change the zip line to:
7z a -tzip "%zipDest%\!foldercounter:~-4!.zip" "%%a" && del "%%a"
The quotes should take care of any spaces.
I want to skip the latest 3 files created and delete the rest of the files. What I need is that if there is text, xml and zip files we need to delete only the zip files and leave the text and xml files behind and the total files left should be 3.If there are 3 or more files other than .zip files, delete all .zip files; if there are less, keep the newest .zip files so that there are 3 files left in total. Can anyone help. I am stuck with this
For example(inside bracket created date of files):
Folder A contains - aa.txt(2/1/18), bb.xml(3/1/18), cc.zip(4/1/18), dd.zip(2/1/18),ee.zip(5/1/18)
What I need after deleting is
aa.txt, bb.xml, ee.zip
This is what I have written
#ECHO OFF
SETLOCAL
SET "targetdir=C:\source"
SET /a retain=3
FOR /f "skip=%retain%delims=" %%a IN (
'dir /b /a-d /o-d "%targetdir%\*.zip" '
) DO DEL (DEL "%targetdir%\%%a.zip"
GOTO :EOF
Given the parameters of your question, a very simple method, although not the most efficient or speedy, would be to do this:
#Echo Off
Set "targetdir=C:\source"
Set "retain=3"
CD /D "%targetdir%" 2>Nul || Exit /B
For /F "Skip=%retain% Delims=" %%A In ('Dir /B/A-D/O-D/TC'
) Do If /I "%%~xA"==".zip" Del "%%A"
I have a folder that contains subfolders with MP4 files. I'm trying to write a script that will move the MP4 files out of the subfolders into the root folder when ran. The batch file I wrote is working, but when the batch script runs again for new subfolders, the MP4 files that were already copied to the root folder, get moved up another level in the file structure. For example:
C:\MainRoot\Root\Subfolder\media.mp4
When script is ran, 'media.mp4' gets moved up to C:\Root\media.mp4 as desired.
But since I need the script to run on a scheduled task. The next time the script runs I get the following:
C:\MainRoot\media.mp4
Instead of just the MP4 file staying in C:\MainRoot\Root.
Here's my batch file so far to copy the mp4 files:
set root_folder=C:\MainRoot\Root
for /f "tokens=1* delims=" %%G in ('dir %root_folder% /b /o:-n /s ^| findstr /i ".mp4" ') do (
move /y "%%G" "%%~dpG..\%%~nxG"
)
What do I need to modify so that once moved, the MP4 files will stay in place?
Any help would be greatly appreciated!
Since all your source files seem to be at a certain directory level, a for /D loop could be wrapped around your for /F loop, which parses the output of a non-recursive dir command line (no /S):
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_ROOT=C:\MainRoot\Root"
set "_PATTERN=*.mp4"
rem // Loop through sub-directories:
for /D %%D in ("%_ROOT%\*") do (
rem // Loop through matching files:
for /F "eol=| delims=" %%F in ('dir /B "%%~fD\%_PATTERN%"') do (
rem // Avoid overwriting destination file:
if not exist "%_ROOT%\%%~nxF" (
rem // Move matching file one level up:
move /Y "%%~fD\%%~nxF" "%_ROOT%\%%~nxF"
)
)
)
endlocal
exit /B
If you are happy to overwrite as in your provided example then something as simple as this may suit your purpose:
#Echo Off
Set root_folder=C:\MainRoot\Root
If /I NOT "%CD%"=="%root_folder%" PushD "%root_folder%" 2>Nul||Exit/B
For /R %%G In (*.mp4) Do If /I NOT "%~dpG"=="%root_folder%\" Move "%%G">Nul 2>&1
If the files are only one folder deep you may prefer this:
#Echo Off
Set root_folder=C:\MainRoot\Root
If /I NOT "%CD%"=="%root_folder%" PushD "%root_folder%" 2>Nul||Exit/B
For /D %%G In (*) Do Move "%%G\*.mp4">Nul 2>&1
I have a bunch of folders, each containing a number of shortcut link files to mp3 files existing in completely separate folders. eg:
/rock-mp3-shortcuts
/jazz-mp3-shortcuts
/funk-mp3-shortcuts
what command would I run (or program to use) to copy all the underlying mp3 files back into the folders of shortcuts that are pointing to them.
I basically want to get all the files in each genre folder of shortcuts to then copy into my portable mp3 player.
This should work:
#echo off
FOR /r %%i in (*.lnk) do call :COPYFILE "%%i"
GOTO:EOF
:COPYFILE
set "filename=%1"
set "filename=%filename:"=%"
set "filename=%filename:\=\\%"
for /f "tokens=1* delims==" %%I in ('wmic path win32_shortcutfile where "name='%filename%'" get target /format:list ^| find "="') do (
set tatgetFile=%%J
copy /y "%tatgetFile%"
)
You'll have to create a bat file and paste my code into it. The file must be located in the folder where all your *.lnk (shortcut) files are. As you have three of them, you will have to copy the bat to each folder and execute it once. You also can automate this and use only one bat but I guess you'll figure out yourself how to do this. It will iterate over all shortcuts and copy the target files to the current folder.
Unfortunately, handling shortcuts in cmd is a pain in the 'a'. That's why we have to use wmic and win32_shortcutfile here.
You can check shortcutJS.bat with which you can create or check info about .lnk.You will need it in the same directory with this code:
#echo off
setlocal
::set your location on the line bellow
set "mp3_dir=c:\mp3_dir"
pushd "%mp3_dir%"
for /r %%# in (*.lnk) do (
for /f "tokens=1* delims=: " %%a in ('shortcutJS.bat -examine "%%~f#"^|find /i "target"') do (
echo location of %%# : %%~fb
rem !!!! remove the echo on the line bellow if everything is ok !!!!
echo copy "%%~fb" "%%~dp#"
)
)
endlocal
I need to copy a file and paste it in many directories, can I do this with a single command in windows prompt?
I tried this code, but it didn't work:
> copy C:\main\folder-1\docs\file.txt C:\main\*\docs
The names are illustratives, but the idea is: inside the "main" folder I have 50 folders ("folder-1", "folder-2", ..., "folder-50")... and inside each "folder-N", I have other folder named "docs". Every time that I create a file into any "folder-N\docs" I need to paste it into all "folder-N\docs".
Is it possible? or I really need to paste the file, folder by folder?
Straight up from the command line:
for /D %x in (c:\main\*.*) DO COPY c:\main\folder-1\docs\file.txt %x\docs\file.txt
From a BAT file or CMD file (not from the command line), you need to escape the % variable again
for /D %%x in (c:\main\*.*) DO COPY c:\main\folder-1\docs\file.txt %%x\docs\file.txt
Of course, if the subdirectory "docs" directory doesn't exist in each subfolder of "main", the iteration will print an error. That's why in my example above I explicitly specify copying to %x\docs\file.txt. If I had just said `%x\docs" as the target of the copy, it might create a file called "docs" that contains the contents of the file.txt source.
More information on for loops here and here:
Or just type "help for" at the command prompt.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir\one"
:: Build list of directorynames
SET "dnames="
FOR /f "delims=" %%a IN ('dir /b /ad "%sourcedir%" ') DO (
IF EXIST "%sourcedir%\%%a\docs\" SET "dnames=!dnames! "%%a""
)
FOR %%a IN (%dnames%) DO FOR %%b IN (%dnames%) DO IF NOT %%a==%%b (
FOR %%s IN ("%sourcedir%\%%~a\docs\*") DO (
IF NOT EXIST "%sourcedir%\%%~b\docs\%%~nxs" ECHO(COPY "%sourcedir%\%%~a\docs\%%~nxs" "%sourcedir%\%%~b\docs\%%~nxs"
)
)
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
The required COPY commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(COPY to COPY to actually copy the files.
I'd suggest that you create a testing subtree of a few small subdirectories before releasing in anger. Remember that this "report" may say to copy the same file from dir1 and dir5 into dir3 but when released because the file would actually be copied from dir1 to dir3, the copy from dir5 would not occur (when the copy from dir5 is checked, the copy from dir1 would already have occurred.)
You could suppress the copy report by appending >nul to the copy line.
Note that this routine is oriented towards one-file-at-a-time and showing what should be done. This following routine should do the same thing, is shorter but doesn't provide an elegant testing structure:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir\one"
:: Build list of directorynames
SET "dnames="
FOR /f "delims=" %%a IN ('dir /b /ad "%sourcedir%" ') DO (
IF EXIST "%sourcedir%\%%a\docs\" SET "dnames=!dnames! "%%a""
)
FOR %%a IN (%dnames%) DO FOR %%b IN (%dnames%) DO IF NOT %%a==%%b (
ECHO(xcopy /d "%sourcedir%\%%~a\docs\*" "%sourcedir%\%%~b\docs\"
)
GOTO :EOF
Again, the xcopy is reported, not executed for testing purposes.