Please explain me this

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Mohammad_Dos
Posts: 84
Joined: 08 Sep 2010 10:25
Location: Iran,Kashan
Contact:

Please explain me this

#1 Post by Mohammad_Dos » 18 Sep 2010 04:09

please explain me this line by line:


Code: Select all

@echo off
        SETLOCAL=ENABLEDELAYEDEXPANSION

        rename test.txt test.tmp
        for /f %%a in (test.tmp) do (
            set linecount=2
            set foo=%%a
            if !foo!==Mohammad_Virus set foo=Abolfazl.E
            echo !foo! >> test.txt)
    del test.tmp


and please explain a little about "for" command

orange_batch
Expert
Posts: 442
Joined: 01 Aug 2010 17:13
Location: Canadian Pacific
Contact:

Re: Please explain me this

#2 Post by orange_batch » 19 Sep 2010 18:00

I'm not going to thoroughly explain this in layman's terms, but...

First of all, I'm going to fix the code, there is some problematic/questionable syntax.

Code: Select all

@echo off&setlocal enabledelayedexpansion

ren "test.txt" "test.tmp"
for /f "usebackq" %%a in ("test.tmp") do (
set linecount=2
set "foo=%%a"
if "!foo!"=="Mohammad_Virus" set "foo=Abolfazl.E"
echo:!foo!>>"test.txt"
)
del "test.tmp"


Explanation:

Code: Select all

@echo off&setlocal enabledelayedexpansion


Prevents displaying of commands to window.
Enables delayed variable expansion using !var!.

The reason for this is, for example:

Code: Select all

set var=10


Code: Select all

for /l %%x in (1,1,5) do set /a var=%var%+1

Trying to add 1 to %var% 5 times. It is read as:

Code: Select all

for /l %%x in (1,1,5) do set /a var=10+1

The result is 11.

Code: Select all

for /l %%x in (1,1,5) do set /a var=!var!+1

This is as-is. !var! is read as it's current value on each iteration of the loop (running of the code).
The result is 15.

Back to your script,

Code: Select all

ren "test.txt" "test.tmp"


Renames the file "test.txt" to "test.tmp".

Code: Select all

for /f "usebackq" %%a in ("test.tmp") do (


for /f iterates (runs the code) for each line of input. In this case, the contents of "test.tmp".
%%a specifies which character the tokens will begin allocating from for the duration of the for loop.
Defaults:
usebackq (off)
eol=;
skip=0
delims=(space)(tab)
tokens=1

Specifying usebackq changes which quotation characters designate what type of set for is iterating over. It's main purpose is to allow you to surround file paths that contain spaces with quotation marks (otherwise they won't work), because without usebackq specified, quotation marks are for processing a text string.

Specifying a character to eol will make for skip/ignore any line that begins with that character. It's to ignore comments, but can be used for other purposes.

Specifying a number to skip simply skips the first however many lines from the input.

delims is any amount of characters that each split up the line being processed. They sit between tokens.

tokens allows you to access any specific piece of the line that's been delimited. Tokens are comma-separated. Placing an asterisk * at the end (or by itself) will allocate all of the text (including delim characters) after the last token to a final token.

For more, read for /? and http://ss64.com/nt/for.html (and related).

So, for each line of text in "test.tmp",

Code: Select all

set linecount=2


Sets the variable linecount to 2. I choose not to use surrounding quotation marks with number variables, to add distinction and because number variables have no use for them.

Code: Select all

set "foo=%%a"


Sets the variable foo to the first token of the current line.
Based on the settings for this for loop, it would be any text up to the first (space) or (tab) in the current line.

Code: Select all

if "!foo!"=="Mohammad_Virus" set "foo=Abolfazl.E"


If the current value of the variable foo is equal to "Mohammad_Virus", set the variable foo to "Abolfazl.E".

Code: Select all

echo:!foo!>>"test.txt"


Appends the value of the variable foo to the file "test.txt".

Code: Select all

)


End of the loop.

Code: Select all

del "test.tmp"


Deletes the file "test.tmp".

I would program it like this, does the same thing:

Code: Select all

@echo off

for /f %%a in ('type "test.txt"^&type nul^>"test.txt"') do (
if "%%a"=="Mohammad_Virus" (echo:AbolFazl.E>>"test.txt") else echo:%%a>>"test.txt"
)


Quick explanation:

Code: Select all

('type "test.txt"^&type nul^>"test.txt"')(


' specifies command output.
type outputs the contents of "test.txt".
& type nul erases the contents of "test.txt". Now it can easily overwrite itself with it's own modified contents.

Code: Select all

if "%%a"=="Mohammad_Virus" (echo:AbolFazl.E>>"test.txt") else echo:%%a>>"test.txt"


If the first token is equal to "Mohammad_Virus", append "AbolFazl.E" to "test.txt", otherwise append the token to "test.txt".

Anyways, I don't know what you're trying to do but if it becomes apparently malicious, I won't help.

Post Reply