Question

I wanna make script, which in document example.txt sort all lines by length (some line has spaces). The longest line will be first line, the shortest line will be at end of the document. Script can rewrite original document. Thank you :-)

Was it helpful?

Solution

It is surprisingly easy and fast to accomplish this by writing each line as its own file within a temporary folder. Then use DIR /B /O-S to sort the files (lines) by size, capturing the result with FOR /F and then printing each file (line) with TYPE.

@echo off
setlocal disableDelayedExpansion

set "file=example.txt"
set "tempLoc=sortLinesTemp"

md "%tempLoc%"
set "cnt=0"
for /f usebackq^ delims^=^ eol^= %%A in ("%file%") do (
  set /a cnt+=1
  set "ln=%%A"
  setlocal enableDelayedExpansion
  echo(!ln!>"%tempLoc%\f!cnt!"
  endlocal
)
(for /f %%F in ('dir /b /o-s "%tempLoc%"') do type "%tempLoc%\%%F")>"%file%.new"
move /y "%file%.new" "%file%" >nul
rd /s /q "%tempLoc%"
type "%file%"

This solution will strip empty lines. Empty lines can be preserved with a bit more code.

Also, line lengths are limited to a bit less than 8191 characters. This limitation is inherent to any pure native batch solution.

OTHER TIPS

This batch file uses a VBS script to help get the line lengths, and sorts, then rewrites the input.txt file into input.new.txt

Use the batch like this: sortline.bat "filename.txt"

Leading | characters in a line will vanish.

@echo off
set "file=%temp%\sortline.vbs"
(
 echo. Const ForReading = 1, ForWriting = 2
 echo. infile = "%~1"
 echo. Set fso = CreateObject("Scripting.FileSystemObject"^)
 echo. Set f1 = fso.OpenTextFile(infile, ForReading^)
 echo. Do While not f1.AtEndOfStream
 echo. f = f1.readline
 echo. Wscript.echo right(10000+len(f^),4^) ^& "|" ^& f
 echo. loop
 echo. f1.close
)>"%file%"
(for /f "tokens=1,* delims=|" %%a in (' cscript //nologo "%file%" ^|sort /r ') do echo(%%b)>"%~n1.new.txt"
del "%file%"

I think this is the simplest and fastest way to do that:

@echo off
setlocal EnableDelayedExpansion

set /A seqNum=10000, accumLen=0
set "lastLine="
for /F "tokens=1* delims=:" %%a in ('findstr /O "^" example.txt') do (
   if not defined lastLine (
      set "lastLine=%%b"
   ) else (
      set /A "seqNum+=1, thisLen=10000-(%%a-accumLen), accumLen=%%a"
      set "line[!thisLen!!seqNum:~-4!]=!lastLine!"
      set "lastLine=%%b"
   )
)
for %%a in (example.txt) do (
   set /A "seqNum+=1, thisLen=10000-(%%~Za-accumLen)"
   set "line[!thisLen!!seqNum:~-4!]=!lastLine!"
)
(for /F "tokens=1* delims==" %%a in ('set line[') do echo %%b) > sorted.txt

This solution strip empty lines and exclamation marks from the file. Both limitations may be fixed, if needed.

You need the strLen function from this page. Also, here is a download link to download sortn.bat , which will give you the hints to get started. Also, you need to be familiar with the basic compare function:

public int compare(String o1, String o2) {             
        if (o1.length()!=o2.length()) {
            return o1.length()-o2.length();
        }
        return o1.compareTo(o2);
    }

Good luck.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top