How to combine logs in order? - windows

I need to combine all my logs, in time and date order, in a batch script.
For example these are my files:
Log_20220805_1200-2340.log
Log_20220805_2340-0230.log
Log_20220806_0230-0725.log
In the first log I have 123
In the second: 456
In the last log: 789
I want to create a new log which combines all to All_Logs.log and contains 123456789(in one line) in order (with the log time help) and I want to delete all other logs
Im using Windows (CRLF)
Please help me, I'm desperate.

del combined.txt
for /f %%b in ('dir /b /od log_????????_????-????') do (
type "%%b">>combined.txt
ECHO del "%%b"
)
should generate a new file with the logs concatenated.
The del commands are echoed for safety during testing. Delete the echo keyword to actually delete the file.
Revision - result in one line.
#ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION
:: You would need to change the value assigned to `sourcedir` to suit your circumstances. The listing uses a setting that suits my system.
:: I deliberately include spaces in names to ensure that the spaces are processed correctly.
SET "sourcedir=u:\your files"
SET "outfilename=all_logs.log"
SET "outline="
for /f "delims=" %%b in ('dir /b /on "%sourcedir%\log_????????_????-????.log"') do (
FOR /f "delims=" %%e IN ('type "%sourcedir%\%%b"') DO SET "outline=!outline!%%e"
ECHO del "%sourcedir%\%%b"
)
IF DEFINED outline (>"%sourcedir%\%outfilename%" ECHO %outline%) ELSE (ECHO DEL "%sourcedir%\%outfilename%" 2^>nul)
GOTO :EOF
Always verify against a test directory before applying to real data.
The del commands are echoed for safety during testing. Delete the echo keyword to actually delete the file.
No idea what (with the log time help) means!

Related

How to make a batch file loop resume from where it was by looping through the files listed on a .txt?

I want to start down mixing hundreds of surround media files in a folder to stereo, but this is a process that will take a lot of time. I'd like to create a batch file that executes my ffmpeg command to this set of files (probably listed in a .txt with dir /s /b) that I can run whenever my PC is on, but also keeps a record of already processed files to be excluded on the next run.
I know I can easily keep track of already processed files by simply adding something like if errorlevel 0 echo "%%~fg">>processed.txt to my loop, but I'm finding it challenging to come up with a way to ignore these files when running the script the next time.
Of course I could always manually edit the file list to be looped and remove the ones already processed, but I wonder if there is a clever way to do it programatically
An example of using a log with findstr. replace the definition of Set "SourceList=%~dp0list.txt" with the filepath of the file used to store the list of files for processing, or modify the for /f loop options to iterate over the output of your Dir command.
#Echo off
If not exist "%TEMP%\%~n0.log" break >"%TEMP%\%~n0.log"
Set "SourceList=%~dp0list.txt"
For /f "usebackq delims=" %%G in ("%sourceList%")Do (
%SystemRoot%\System32\Findstr.exe /xlc:"%%G" "%TEMP%\%~n0.log" >nul && (
Rem item already processed and appended to log. do nothing.
) || (
Rem item does not exist in log. Proccess and append to log.
Echo(Proccess %%G
>>"%TEMP%\%~n0.log" Echo(%%G
)
)
I managed to produce a way that doesn't rely on external tools and executes the job only with for loops. As it was needed to use UTF-8, extra steps were taken to properly revert the codepage after the batch file ended:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "tokens=*" %%G in ('%SystemRoot%\System32\chcp.com') do for %%H in (%%G) do set /A "CodePage=%%H" 2>nul
%SystemRoot%\System32\chcp.com 65001 >nul 2>&1
if not exist "%~dpn0.log" break >"%~dpn0.log"
set "FileList=%~dp0FileList.txt"
set "LogFile=%~dpn0.log"
for /f "usebackq delims=" %%G in ("%FileList%") do (
set "SkipFile="
for /f "usebackq delims=" %%H in ("%LogFile%") do (
if "%%G" == "%%H" (
set "SkipFile=1"
)
)
if not defined SkipFile (
echo --^> Processing file "%%~nG"
rem file is processed
) else (
echo "%%~nG" has already been processed
rem file is not processed
)
)
%SystemRoot%\System32\chcp.com %CodePage% >nul
endlocal
As can be seen, part of this answer is inspired by #T3RROR's!

Windows Batch renaming from text document

I made a Batch script to rename a large amount of files. It takes their name and searches for it in a text document, copies the line and takes the data I need from it and then renames the file.
It seems to work fine for the most part, but I can't check to see how it's doing because it is constantly producing errors/warnings in the console.
#echo off
set ogg=.ogg
Setlocal EnableDelayedExpansion
for %%a in (*.ogg) do (
set fileNameFull=%%a
set fileName=!fileNameFull:~0,-4!
for /F "delims=" %%a in ('findstr /I !fileName! strings.txt') do (
endlocal
set "stringLine=%%a%ogg%"
)
Setlocal EnableDelayedExpansion
set fullString=!stringLine:~26!
ren %%a "!fullString!"
)
pause
The code works, I'd just like to be able to track progress, as 10,000s of files are being renamed at a time and I've no indication of how far along the process is.
The errors are:
"FINDSTR: Cannot open [...]"
"The syntax of the command is incorrect."
#echo off
Setlocal EnableDelayedExpansion
for %%a in (*.ogg) do (
for /F "delims=" %%q in ('findstr /I /L /c:"%%~na" strings.txt') do (
set "stringLine=%%q"
)
ECHO ren "%%a" "!stringLine:~26!.ogg"
)
pause
This code should be equivalent, but fixed, to the code you've posted.
Fixes:
Removed the endlocal/setlocal complication - not required
changed the inner `for` metavariable - must not be duplicate `%%a`
Changed the `findstr` switches - add `/L` for literal and `/c:` to force single token in case of a separator-in-name; use `%%~na` to specify "the name part of `%%a`" to avoid the substringing gymnastics.
removed said gymnastics
Removed 2-stage string manipulation of destination filename
Removed superfluous setting of `ogg`
The resultant code should duplicate what you have originally, except that it will simply report the rename instruction. You should test this against a small representative sample to verify.
for counting/progress:
set /a count=0
for %%a in (*.ogg) do (
for /F "delims=" %%q in ('findstr /I /L /c:"%%~na" strings.txt') do (
set "stringLine=%%q"
)
ECHO ren "%%a" "!stringLine:~26!.ogg"
set /a count +=1
set /a stringline= count %% 1000
if %stringline% equ 0 echo !count! Processed
)
pause
which should show you progress each 1000.
You could use
if %stringline% equ 0 echo !count! Processed&pause
to wait for user-action before progressing...
BTW -I'm making the assumption that the newname is from column 27+ in your file, since you've not shown us a sample.Also, you should be aware that a simple findstr would locate the target string as a substring anywhere within the file - either as the newname or the oldname. If you invoke the /B switch on the findstr, then the string will match at the very beginning of the line only.

Keep X amount of files in folder, forfiles

I would like to keep the X latest files from a folder and delete the rest. Is this possible with FORFILES? If it's not I can fallback to another solution I seen here. Thanks for help.
I did this but it takes by dates: EDIT
forfiles /p [path] /s /d -5 /c "cmd /c echo #file"
(echo file for testing purpose)
#ECHO OFF
SETLOCAL
SET "targetdir=U:\destdir"
SET /a retain=10
FOR /f "skip=%retain%delims=" %%a IN (
'dir /b /a-d /o-d "%targetdir%\*" '
) DO ECHO (DEL "%targetdir%\%%a"
GOTO :EOF
You would need to change the setting of targetdir to suit your circumstances. Equally, this procedure targets all files - change the filemask to suit.
The required DEL commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(DEL to DEL to actually delete the files.
method is to simply execute a dir in basic form without directories, sorted in reverse-date order.
Skip the first 10 entries, and delete the rest.
With forfiles I see no chance to accomplish your task of returning the newest (most recent) number of files.
So my idea for this approach is this:
to use dir /B /A:-D /T:C /O:-D to retrieve a bare list (/B) of files (no directories, /A:-D), sorted by creation date (/T:C; if you want to use the last modification date, simply remove the /T:C portion) in decending order (/O:-D), meaning newest items first;
to put over a for /F "eol=| delims=" loop to gather and parse the dir output line by line, meaning file by file, not excluding file names beginning with ; (eol=|, | is illegal for file names) and not splitting file names containing white-spaces like SPACE or TAB (delims=);
to establish a variable that constitutes a counter, incremented per each loop iteration;
to place an if condition inside of the loop to check if the counter reached the desired limit number and in case it is fulfilled, to break the for /F loop by goto;
Here is the related code:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Define global constants here:
set "TARGETPATH=\path\to\files\*.*"
set /A "TOTAL=10"
set /A "COUNT=0"
for /F "eol=| delims=" %%F in ('
dir /B /A:-D /T:C /O:-D "%TARGETPATH%"
') do (
echo(%%F
set /A COUNT+=1
setlocal EnableDelayedExpansion
if !COUNT! GEQ %TOTAL% (
endlocal
goto :NEXT
) else (
endlocal
)
)
:NEXT
endlocal
exit /B
I toggled the delayed variable expansion within the for /F loop to avoid trouble in case file names contain exclamation marks !, which would get lost in the line echo(%%F in case it is on.
Update
The following code accomplishes the original task of your question, namely to delete files in a given directory but to keep the most recent number of files:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Define global constants here:
set "TARGETPATH=\path\to\files\*.*"
set /A "TOTAL=10"
set "SKIPOPT=" & if %TOTAL% GTR 0 set "SKIPOPT=skip=%TOTAL% "
for /F "%SKIPOPT%eol=| delims=" %%F in ('
dir /B /A:-D /T:C /O:-D "%TARGETPATH%"
') do (
del /P "%%F"
)
endlocal
exit /B
Since for /F supports a skip= to skip the given number of lines, and so files in our situation, let us make use of it. It is given indirectly here via variable SKIPOPT, which holds the entire option string like skip=10 (given that TOTAL is set to 10). The if %TOTAL% GTR 0 query is implemented for the script not to fail in case TOTAL is 0, because for /F does not accept the option skip=0.
The /P switch at the del command lets appear a prompt Delete (Y/N)? for testing purposes. If you do not want any prompts, simply remove it.

Batch file for /f isnt reading files

Lots of issues With batch coding... Things just don't seem to work the way i expect them to.
So I am Using a batch file to Extract Text data from .as Files. I managed to get that working However It creates a bunch of Junk/empty txt files that don't have any useful content extracted from them. So I made another batch file that gets called from main.bat and is supposed to Clean the empty files, however the variables are incorrect even though the for loop in main.bat is almost identical.
Full Copies of the batch files main.bat and Clean.bat
The Issue Is the Bit of Code below (From Clean.bat line 33) #note the following code had most of its counters and echos removed
#echo off
cls
setlocal enabledelayedexpansion
for /r %%Z in (*.txt) do (
SET /a count=0
for /F "eol= tokens=1 delims=," %%A in ("%%Z") do (
if /i %%A==LN set /a count+=1
)
if !count! EQU 0 (
rem del "%%Z")
)
pause
In this Code %%A and %%Z Are both Equal to The Full File Path of the file that should be getting read from. When %%A should be token 1 of The txt file in question. Because of this count always = 0 so it always deletes the file (thats why del is commented out).
Here's an Example of the file its supposed to read from
LN,296,textE("海沿いに立つ高級フィットネスリゾート施設。");
LN,299,textE("夏休み、俺たち兄妹は、陸上の強化合宿という「名目」のもと、\nこの施設を訪れていた。");
LN,302,textE("莉 央\nすごい、すごい!!おしゃれなところだねー!");
Basically Its supposed to check each line and if LN doesnt Exist as the first token to any line it deletes the file. (Because that means the file is empty except for a Line count of the Original .as file)
This may work for you given the things you have said:
I interpreted your point to mean that if the file doesn't contain LN as the first token on any line, then it is to be deleted.
#echo off
for /r %%Z in (*.txt) do (
SET "count="
for /F "usebackq delims=," %%A in ("%%Z") do (
if /i "%%A"=="LN" set count=1
)
if not defined count echo del "%%Z"
)
pause
This is another way to do the same thing:
#echo off
for /r %%Z in (*.txt) do (
findstr "^LN," "%%Z" >nul || echo del "%%Z"
)
pause

.bat - Create a menu from folder file list

I don't usually create .bat file, but I made this little script useful for develop.
I'm using this for reading and creating a list of files contained into a folder:
for /f "delims=|" %%f in ('dir /b C:\src\release\android\') do echo %%f
and I found this about how to create a menu starting from a list of file -> Multiple choices menu on batch file?
Now my question is:
I'd like to create a menu with a list of files contained into that folder which I can select (not multiple selection) by pressing it's relative number on the list, but i don't really know how to merge the two bit of code above.
The final result should work something like:
[1] ..
[2] ..
[3] ..
[4] ..
select file:
and it will install the selected file from the folder.
Any suggestion would be really appreciated.
Thanks in advance
This should work unless you're using a version of Windows that doesn't have choice, like if you're still on XP for some reason.
#echo off
setlocal enabledelayedexpansion
set count=0
set "choice_options="
for /F "delims=" %%A in ('dir /a:-d /b C:\src\release\android\') do (
REM Increment %count% here so that it doesn't get incremented later
set /a count+=1
REM Add the file name to the options array
set "options[!count!]=%%A"
REM Add the new option to the list of existing options
set choice_options=!choice_options!!count!
)
for /L %%A in (1,1,!count!) do echo [%%A]. !options[%%A]!
choice /c:!choice_options! /n /m "Enter a file to load: "
:: CHOICE selections get set to the system variable %errorlevel%
:: The whole thing is wrapped in quotes to handle file names with spaces in them
:: I'm using type because I'm not familiar with adb, but you be able to get the idea
type "C:\src\release\android\!options[%errorlevel%]!"
Improving upon SomethingDark's script to run Python scripts in a user's Document folder (I know, not best practice here for brevity's sake), as it currently wouldn't work when there are more than 10 choices:
#echo off
setlocal enabledelayedexpansion
set count=0
set "choice_options="
for /F "delims=" %%A in ('dir /a:-d /b C:\Users\JohnSmith\Documents\*.py') do (
REM Increment %count% here so that it doesn't get incremented later
set /a count+=1
REM Add the file name to the options array
set "options[!count!]=%%A"
)
for /L %%A in (1,1,!count!) do echo [%%A]. !options[%%A]!
::prompts user input
set /p filechoice="Enter a file to load: "
:: Location of python.exe and location of python script explicitly stated
echo Running !options[%filechoice%]!...
"C:\Users\JohnSmith\AppData\Local\Microsoft\WindowsApps\python.exe" "C:\Users\JohnSmith\Documents\!options[%filechoice%]!"

Resources