How to randomly rearrange lines in a text file usi

2020-02-14 06:41发布

问题:

I am creating a code that strips through different MAC addresses randomly, but cannot figure out how to do this. My thought on how to approach this is to randomize or rearrange the order of the MAC address in the text file with this script, but I cannot figure out how to do this with a batch file. How this will work is that it will read "maclist.txt", then create a new temp file with the random order "maclist_temp.txt", that will be the rearranged file. Then, it will pull this randomized file in order.

I have tried Google and searching the web, but I haven't found anything too useful. I'm still actively looking, but any advice would be extremely useful.

Something as simple as extracting and deleting a random line and then adding to the bottom might work. Randomization would be better though, but I want to keep the original list. Something like:

  1. Make a temp copy of maclist.txt called maclist_temp.txt
  2. Take one random MAC address, remove it from maclist_temp.txt
  3. Readd it to the bottom

That is all I want, but any suggestions are welcome.

回答1:

You may try this batch file to help you to shuffle your maclist.txt. The usage of the batch code is

C:\> type list.txt | shuffle.bat > maclist_temp.txt

After issuing this command, maclist_temp.txt will contain a randomized list of MAC address.

Hope this helps.



回答2:

Here is a simpler method to randomize/randomise a file, no temp files needed. You can even reuse the same input filename.

Limitations are: blank lines and line starting with ; will be skipped, and lines starting with = will have all leading = signs stripped and ^ characters are doubled.

@echo off
setlocal
for /f "delims=" %%a in (maclist.txt) do call set "$$%%random%%=%%a"
(for /f "tokens=1,* delims==" %%a in ('set $$') do echo(%%b)>newmaclist.txt
endlocal


回答3:

This seems to work. Feed it a command line parameter of the file to randomize.

    @echo off
    setlocal EnableDelayedExpansion

    rem read the number of lines in the file
    rem the find prepends the line number so we catch blank lines
    for /f "delims=" %%n in ('find /c /v "" %1') do set "len=%%n"
    set len=!len:*: =!
    rem echo %1 has %len% lines

    rem Relocate as many lines as there are lines in the file
    for /l %%j in (1 1 !len!) do (
      rem echo starting round %%j

      rem geta random number between 1 and the number of lines in the file
      set /a var=!random! %% !len! + 1
      rem echo relocating line !var!

      rem make sure there is no temp file
      if exist %1.temp del %1.temp

      rem read each line of the file, write any that don't match and then write the one that does
      <%1 (
        for /l %%i in (1 1 !len!) do (

          rem if it is the target line then save it
          if %%i == !var! (
            set /p found=
            rem echo saving !found!
          )

          rem if it is the target line then write it
          if not %%i == !var! (
            set /p other=
            rem echo writing !other!
            echo !other!>> %1.temp
          )
        )
        rem now write the target line at the end
        rem echo appending !found!
        echo !found!>> %1.temp
      )

      rem replace the original with the temp version
      move %1.temp %1>nul
    )

    rem print the result
    type %1


回答4:

Place in cmd file

for /f "tokens=2 delims=/" %%m in ('cmd /e:on /v:on /c "for /f %%f in (maclist.txt) do @echo !random!/%%f" ^| sort') do echo %%m

It spawns a cmd which reads the mac list in the inner for, prefixes a random value and a slash to the mac and sorts the list. Then this list is splitted in the outter for using the slash as delimiter and printing the mac address.



回答5:

I really like foxidrive's approach. Nevertheless I want to provide a solution with all the listed limitations eliminated (although cmd-related restrictions like file sizes < 2 GiB and line lengths < ~ 8 KiB remain).

The key is delayed expansion which needs to be toggled to not lose explamation marks. This solves all the potential problems with special characters like ^, &, %, !, (, ), <, >, | and ".

The counter index has been implemented in order not to lose a single line of the original text file, which could happen without, because random may return duplicate values; with index appended, the resulting variable names $$!random!.!index! are unique.

The findstr /N /R "^" command precedes every line of the original file with a line number followed by a colon. So no line appears empty to the for /F loop which would ignore such. The line number also implicitly solves the issue with leading semicolons, the default eol character of for /F.

Finally, everything up to and including the first colon (remember the said prefix added by findstr) is removed from every line before being output, hence no more leading equal-to signs are dismissed.

So here is the code:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

set /A "index=0"
for /f "delims=" %%a in ('findstr /N /R "^" "%~dpn0.lst"') do (
    setlocal EnableDelayedExpansion
    for /F %%b in ("$$!random!.!index!") do (
        endlocal
        set "%%b=%%a"
    )
    set /A "index+=1"
)
> "%~dpn0.new" (
    for /f "delims=" %%a in ('set $$') do (
        set "item=%%a"
        setlocal EnableDelayedExpansion
        echo(!item:*:=!
        endlocal
    )
)

endlocal
exit /B