Discussion forum for all Windows batch related topics.
Moderator: DosItHelp
-
AlphaInc.
- Posts: 21
- Joined: 15 Apr 2021 08:15
#1
Post
by AlphaInc. » 09 Aug 2021 06:44
hello everybody,
while working on my script that outputs mediainfo to a text-file for multiple videos and wanted to merge them together:
Code: Select all
set /A fileCounter=0
for %%A in (.mkv) do (
set /A "fileCounter+=1"
set "name=%%A"
setlocal EnableDelayedExpansion
C:\System\Mediainfo\MediaInfo.exe --Inform=file://C:\System\Mediainfo\alphaMeta_template.txt "%%A" >> C:\System\Mediainfo\Outputs\tmp\photo_!fileCounter!.txt
endlocal
)
type C:\System\Mediainfo\Outputs\tmp\video_*.txt >> C:\System\Mediainfo\Outputs\master\allVideos.txt
Now i noticed that the order of the files is a little mixed up. When listing all the files I found out that after file #1 there comes file #10-19 and then #2 (following #20-29).
My question is, can you change the syntax (not only for merging but also for creating the outputs) to go from 1 to 20 (for example; could also be to number 200) in a normal order (like you would count in real life and also how Windows Explorers sorts them) ?
Last edited by
AlphaInc. on 10 Jul 2022 03:14, edited 1 time in total.
-
aGerman
- Expert
- Posts: 4678
- Joined: 22 Jan 2010 18:01
- Location: Germany
#2
Post
by aGerman » 09 Aug 2021 07:57
Well, obviously file names are strings where comparisions are performed from left to right and where the 1 in string "10" is just less than the 2 in string "2". A fixed length (with leading zeros) could help. However, I'm not sure the numbering of files is the right concept. You're already struggling with the counter and delayed variable expansion. Why don't you use the file name of your mkv files instead? FOR variables support nice modifiers. Have a look at what you get for %%~nA or %%~dpnA. Append extension .txt and you're done ...
Steffen
-
kwsiebert
- Posts: 43
- Joined: 20 Jan 2016 15:46
#3
Post
by kwsiebert » 09 Aug 2021 10:19
I suggest adopting a file naming syntax that uses leading zeroes to pad all numbers to the same digit count. You probably also want to sort the file list before doing anything where you care about file order, even that Type command at the end. Newer versions of Windows Explorer do a smart sort on numeric filenames with different digit counts, but the command line (and Explorer under Windows XP and older) treats them as text, so when working with numbers of different lengths, the shorter ones always come first. It gets worse if you are accessing files stored on a Unix network share, and instead of alphabetically you might instead get them by file date.
-
aGerman
- Expert
- Posts: 4678
- Joined: 22 Jan 2010 18:01
- Location: Germany
#4
Post
by aGerman » 09 Aug 2021 10:32
kwsiebert wrote: ↑09 Aug 2021 10:19
Newer versions of Windows Explorer do a smart sort on numeric filenames with different digit counts
The StrCmpLogicalW() API function is used. Once I wrapped it in a PowerShell macro.
viewtopic.php?f=3&t=9220#p60049
Example:
Code: Select all
@echo off &setlocal
:: %logicalsort_asc% and %logicalsort_desc% macros
:: sort a list of lines in an Explorer-like manner
:: strings are read from standard input and written to standard output
set logicalsort_asc=powershell -nop -ep Bypass -c ^"try{^
%=% Add-Type '^
%=====% using System.Runtime.InteropServices;^
%=====% public class SCmpLgcl : System.Collections.Generic.IComparer^<string^>{^
%=========% [DllImport(\"shlwapi.dll\",CharSet=CharSet.Unicode)]^
%=========% static extern int StrCmpLogicalW(string a,string b);^
%=========% public SCmpLgcl(){}^
%=========% public int Compare(string a,string b){return StrCmpLogicalW(a,b);}^
%=====% }';^
%=% $list=[System.Collections.Generic.List[string]]@($Input);^
%=% $list.Sort([SCmpLgcl]::new());^
%=% $list;^
%=% exit 0;}catch{exit 1;}^"
(set logicalsort_desc=%logicalsort_asc:(a,b)=(b,a)%)
md "%temp%\sorttest"
pushd "%temp%\sorttest"
>"abc.txt" type nul
>"xyz.txt" type nul
>"foo100.txt" type nul
>"foo20.txt" type nul
>"foo3.txt" type nul
echo ~~~~~~~~~~~~~~ default:
for /f "delims=" %%i in ('dir /a-d /b "*.txt"') do echo do something with "%%i"
echo ~~~~~~~~~~~~~~ logically ascending:
for /f "delims=" %%i in ('dir /a-d /b "*.txt" ^| %logicalsort_asc%') do echo do something with "%%i"
echo ~~~~~~~~~~~~~~ logically descending:
for /f "delims=" %%i in ('dir /a-d /b "*.txt" ^| %logicalsort_desc%') do echo do something with "%%i"
echo ~~~~~~~~~~~~~~
popd
pause
rd /s /q "%temp%\sorttest"
Output:
~~~~~~~~~~~~~~ default:
do something with "abc.txt"
do something with "foo100.txt"
do something with "foo20.txt"
do something with "foo3.txt"
do something with "xyz.txt"
~~~~~~~~~~~~~~ logically ascending:
do something with "abc.txt"
do something with "foo3.txt"
do something with "foo20.txt"
do something with "foo100.txt"
do something with "xyz.txt"
~~~~~~~~~~~~~~ logically descending:
do something with "xyz.txt"
do something with "foo100.txt"
do something with "foo20.txt"
do something with "foo3.txt"
do something with "abc.txt"
~~~~~~~~~~~~~~
Drücken Sie eine beliebige Taste . . .
Steffen
-
AlphaInc.
- Posts: 21
- Joined: 15 Apr 2021 08:15
#5
Post
by AlphaInc. » 09 Aug 2021 13:25
Can I combine your script with mine and if yes, how ?
-
aGerman
- Expert
- Posts: 4678
- Joined: 22 Jan 2010 18:01
- Location: Germany
#6
Post
by aGerman » 09 Aug 2021 13:52
What have you tried?
untested:
Code: Select all
pushd "C:\System\Mediainfo\Outputs\tmp"
for /f "delims=" %%i in ('dir /a-d /b "video_*.txt" ^| %logicalsort_asc%') do >>"C:\System\Mediainfo\Outputs\master\allVideos.txt" type "%%i"
popd
Why all the temporary "video_*.txt" files? Why don't you append the output directly to "allVideos.txt"? I don't get the logic behind your programming design ¯\_(ツ)_/¯
Steffen