3

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.

  • You'll need to have two temp files at-least, and a nested `for` loop – Monacraft Oct 16 '13 at 00:09
  • If on Linux , these might help : [Select random lines from a file in bash](http://stackoverflow.com/questions/9245638/select-random-lines-from-a-file-in-bash) , [What's an easy way to read random line from a file in Unix command line?](http://stackoverflow.com/questions/448005/whats-an-easy-way-to-read-random-line-from-a-file-in-unix-command-line) – Uours Oct 16 '13 at 00:25
  • I'm not on Linux, I'm a Windows 7 user. Also, what's a nested for loop? – computerlife22 Oct 16 '13 at 00:37
  • @computerlife22 it refers to a loop inside a loop – Dale Oct 16 '13 at 01:05

5 Answers5

7

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

Here are the contents of shuffle.bat:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET TmpFile=tmp%RANDOM%%RANDOM%.tmp
TYPE NUL >%Tmpfile%
FOR /F "tokens=*" %%i IN ('MORE') DO SET Key=!RANDOM!!RANDOM!!RANDOM!000000000000& ECHO !Key:~0,15!%%i>> %TmpFile%
FOR /F "tokens=*" %%i IN ('TYPE %TmpFile% ^| SORT') DO SET Line=%%i&ECHO.!Line:~15!
::DEL %TmpFile%
ENDLOCAL

After issuing the above command, maclist_temp.txt will contain a randomized list of MAC addresses.

Hope this helps.

emallove
  • 1,417
  • 1
  • 17
  • 22
Dale
  • 1,903
  • 1
  • 16
  • 24
5

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
foxidrive
  • 40,353
  • 10
  • 53
  • 68
  • There is one more limitation: literal `%` signs get lost... great approach though! Perhaps you are interested in [my answer](http://stackoverflow.com/a/39008715) that also fixes the problem with potential duplicate `random` numbers... – aschipfl Aug 18 '16 at 01:52
  • When the echo statement executes, echo _must_ be off, therefore `@echo(%%b)` is essential. – hunterhogan Jun 12 '23 at 03:38
2

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
Community
  • 1
  • 1
aschipfl
  • 33,626
  • 12
  • 54
  • 99
  • Great Job here! How can I use multiple files at once? I added a new file in first `for` and duplicate the second `For` but not working properly – Ionut Bejinariu Jan 15 '23 at 06:14
  • Thanks, @IonutBejinariu! Well, the easiest approach is to wrap the code into a `for` loop: 1. replace in the script `%~dpn0.lst` by `%%~F` and `%~dpn0.new` by `%%~nF.new`; 2. insert after the first `setlocal` command line: `for %%F in ("file1.lst" "file2.lst" "files*.lst") do (`; 3. insert before the last `endlocal` command: `)`… – aschipfl Jan 17 '23 at 18:06
  • Thank you, I will try .. hope I will succeed... I am a beginner in this. :) – Ionut Bejinariu Jan 17 '23 at 18:13
  • I did exactly as you said, but not working. `file.new` is not merged with original and remain in folder also the big problem is that the script mix the lines of all files between them. – Ionut Bejinariu Jan 17 '23 at 20:49
  • also join lines between files, instead of 5 I have 26 lines in fourth file.new ,, first file doubled, second triple, and the third files is 4 time more the lines than original – Ionut Bejinariu Jan 17 '23 at 20:58
  • @aschiphl any other advice? – Ionut Bejinariu Jan 21 '23 at 22:55
1

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
Jerry Jeremiah
  • 9,045
  • 2
  • 23
  • 32
1

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.

MC ND
  • 69,615
  • 8
  • 84
  • 126