Naturally Sort Files in Batch - sorting

I have a folder with 20 some files and am wanting to sort them similar to the way Windows Explorer does. The files I have all have prefixes of block sizes like so:
1024KB.log
32KB.log
64KB.log
4KB.log
256KB.log
512KB.log
But when I sort them in batch, it only looks at the first digit then sorts them like so:
1024KB.log
256KB.log
32KB.log
4KB.log
512KB.log
64KB.log
I want to sort them by smallest to largest block size. Any ideas?
EDIT: I also have to keep the file name integrity because I then call another script which uses the file names and creates strings.

Take Command - the CMD.EXE replacement has natural sorting.
If you can pad the filenames with zeros then a normal sort will return them ok.
This code will return them sorted numerically:
#echo off
type nul>1024KB.log
type nul>32KB.log
type nul>64KB.log
type nul>4KB.log
type nul>256KB.log
type nul>512KB.log
setlocal enabledelayedexpansion
for %%a in (*.log) do (
set num=0000000000%%a
set num=!num:~-14!
set $!num!=%%a
)
for /f "tokens=1,* delims==" %%a in ('set $0') do echo %%b
pause

Related

I need to display ordered list of files on my hard drive "c:" with the help of cmd. we should order files by size

I need to display ordered list of files on my hard drive "c:". we should order files by size. When i do it, I have problem. Every directory dispays grouped. For example on my hard drive are 2 directories : 1-st- "55" and it has some files. 2-nd-"66" and that directory also has some files and 3 files. When i tried to display ordered list of files i saw next: first dispayed all 3 files from hard drive "\c" then displayed files from directory "55" and next to them dispalyed files from directory "66". How can i display all files and order them by size withot ftouping them by directories. I used command dir /a-d /s /o-s /b
As Mofi already mentioned, dir isn't built to do that. You have to build a list ("array") of the files and their size, then sort by size. I'm not sure if you need just the bare sorted list of files or their size too, so adapt the echo statement to your needs. You can simply reverse the sort order with sort parameter /r
#echo off
setlocal enabledelayedexpansion
set cnt=10000
for /r %%a in (*) do (
set /a cnt+=1
set "siz= %%~za"
set "file[!cnt!]=!siz:~-10! %%~fa"
)
REM for debug: set file[
for /f "tokens=2,* delims= " %%a in ('set file[ ^| sort /+15') do (
echo %%a - %%b
)
set file[ lists all variables (I started with 10000 to get the variable names to the same length for sort /+15 to work properly - adapt if you might have more than 89998 files),
sort can't handle natural numbers, it sorts strictly based on ASCII values, so we have to prepend the length with spaces or zeroes and get all of them to the same length for sort to work "properly" (a.k.a to "human standards").
sort /+15 starts sorting at the 15th character of each line and so ignores the variable name - adapt the 15 accordingly if you change 10000 or the file[...] variable name.
Also increase the number of spaces (currently 10) and the 10 in :~-10 if you might have file sizes in the Gigabyte range.

Batch script to read numerical part of file and rename with next higher integer

I have a file, such as -
foofile_1.ext
A script should read the numerical part of the file, and then rename the file with the next integer, i.e., after execution, the file name should be
foofile_2.ext
I can do it with a C++ / c application or even in bash but not sure how to write a batch script to perform this rename. The filename before the _ isn't going to change, and _ will aaways appear in the same position within the filename.
I can strip the filename to _, but recognizing the numerical is an implementation I am not familiar with. Once I recognize the numerical, I can increment it and rename the file.
Something to consider is that renaming foofile_1.ext to foofile_2.ext will fail should foofile_2.ext already exist. One way to get around it is to rename in descending numerical order, I posted an answer like that before on SO.
I am however not going to post the same answer here, nor link that answer. I will however show one other method:
#echo off
setlocal enabledelayedexpansion
for /f "tokens=1,*delims=_" %%i in ('dir /b /a-d "*_*.ext"') do (
echo %%~nj | findstr /R /V /C:"[A-Z]">nul && (
set /a numeric=%%~nj+1
ren "%%~i_%%~j" "%%~i_-hld-!numeric!%%~xj"
)
)
for /f "delims=" %%f in ('dir /b /a-d "*_-hld-*.ext"') do (
set "name=%%~f"
ren "%%~f" !name:-hld-=!
)
Considering that your input is as you said and does not contain earlier _'s anywhere. This will just take each file with the *_*.ext format. We split by the _ into two tokened metavaiables (%%i and %%j) We take the numeric value and increment by one, then rejoin %%i which is pre _. This however is where the problem comes when the file you are trying to rename to exists, so for that, first we test if %%~nj does not have Alphabetical characters only, using findstr (not doing special characters in this free code) Secondly we give a temporary addition to the name to prevent name clashing.
Once we are done, we simply do a rename on all the files containing the _-hld- temp inclusion.

Split txt file delimited by space or comma and concatenate a suffix in a .bat

I need to split some text in lines and concatenate with a sufix using Windows cmd .bat.
I recieve lists that came like:
9448
9453
9463
9464
9474
9477
or like:
9448, 9453, 9463, 9464, 9474, 9477
So I need to put every number of these added with .jpg, like:
9448.jpg
9453.jpg
9463.jpg
them the program would run the way I need.
here goes the code I'm working on:
echo off
for %%a in (.) do set currentfolder=%%~na
set src_folder= %CD%
set dst_folder= "%currentfolder%_SELECTED/%date:/=%%"
md %dst_folder%
for /f %%i in (list.txt) DO copy %%i %dst_folder%\%%i
run two nested for loops: one to split into lines and another to split a line into separate tokens. So you don't have to care, which of the two formats the file has.
#echo off
for /f "delims=" %%a in (list.txt) do (
for %%b in (%%a) do (
ECHO copy "%%b.jpg" "%dst_folder%\%%b"
)
)
Note: it isn't clear to me, what you exactly try to do. Adapt the ECHO line until the output is what you want, then remove the ECHO.

How to sort a file on multiple positions using Windows command line?

I have an index text file, and I'm having trouble sorting it. I've been looking online for an answer, but Google hasn't pulled up anything with multi-positional searches.
Trying to do so with Unix (which would be easy), would be done as
sort inputfile -k1.1 -k3.3 -o outputfile
should accomplish the task, but trying to do so gives me Cygwin errors of already specifying the input twice (UNIX sorts are out!).
I need to sort this index file, either with Windows console applications or Perl on both positions.
Here is the input data:
1925699|0003352_0050003895.pdf|00500003895|0003352
1682628|0003352_0050003894.pdf|00500003894|0003352
1682628|0003352_0050003893.pdf|00500003893|0003352
The desired output is:
1682628|0003352_0050003893.pdf|00500003893|0003352
1682628|0003352_0050003894.pdf|00500003894|0003352
1925699|0003352_0050003895.pdf|00500003895|0003352
I'm currently trying to use:
sort/+1,7 /+32,11 < inputfile > outputfile
But I've failed to get this to be successful. (It only sorts the first parameter.) Again Unix is out of the question, and I can do it in Perl, but can this be done in Windows command line?
#ECHO Off
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "filename1=%sourcedir%\q45575219.txt"
SET "outfile=%destdir%\outfile.txt"
SET "tempfile=%destdir%\tempfile.txt"
(
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
FOR /f "tokens=1,3delims=|" %%s IN ("%%a") DO (
ECHO(%%s%%t^|%%a
)
)
)>"%tempfile%"
(
FOR /f "tokens=1*delims=|" %%a IN (' sort "%tempfile%" ' ) DO ECHO(%%b
)>"%outfile%"
DEL "%tempfile%"
GOTO :EOF
You would need to change the settings of sourcedir and destdir to suit your circumstances.
I used a file named q45575219.txt containing your data for my testing.
Produces the file defined as %outfile%
Uses a temporary file defined as %tempfile%
Read the source file, assigning each line to %%a. Analyse %%a using pipe as a delimiter and select the first and third tokens. Prefix the first and third tokens to the entire line, separated by a pipe and echo into a temporary file.
sort the temporary file, tokenise again on pipe, selecting the first token (before the first pipe) and the rest of the line; output only the rest to the destination file.

Batch: how do you bulk rename files (getting close)?

I've seen people do this in Perl, but I'm wondering if there's a way to do it via batch? It's built into Windows, so I think it would be more useful to know how to do this with a batch script. It doesn't require installing anything onto a computer.
An example input name: myFile_55
An example output pattern: change myFile to picture and reduce the number by 13.
An example output: picture_42.
How would you approach this? I know a batch command to rename:
ren myFile_55 picture_42.
So, if I have a file named renamer.bat, I can add the following:
for /r %%x in (%1) do ren "%%x" %2.
Then I can type this command:
renamer.bat myfile* picture*.
I don't know how to reduce the numbers, though.
You can probably put the original file name through a for loop, and extract the name and numbers, do the math on the numbers, then plug it back in with the new name and number. As long as the filename format is name_number you can use this:
REM Allow for numbers to be iterated within the for-loop i.e. the i - z
SETLOCAL ENABLEDELAYEDEXPANSION
SET i=0
SET z=13
SET newName=picture
SET workDir=C:\Path\To\Files
REM Given that filenames are in the format of 'Name_number', we're going to extract 'number
REM and set it to the i variables, then subtract it by 13, then rename the original file
REM to what the newName_x which if the filename was oldName_23 it would now be newName_10
FOR /r %%X in (%1) do (
FOR /F "tokens=1-2 delims=_" %%A IN ("%%X") DO (
SET i=%%B
SET /A x=!i! - %z%
REM ~dpX refers to the drive and path of the file
REN "%%~dpX\%%A_%%B" "%newName%_!x!"
)
)
EDIT: Edited the REN command to include the drive and path of the original file. Changed from lower case x to upper case X as to not confuse %%~dpX.

Resources