Change the last 20 lines of a text file - windows

How do I change only last 20 lines and not the all the contents.
#echo off > newfile & setLocal enableDELAYedexpansion
copy /Y E:\LOG.DIR LOG.DIR
set old=INACTIVE
set new=ACTIVE
for /f "tokens=* delims=" %%a in (LOG.DIR) do (
set str=%%a
echo %SOON
set str=!str:%old%=%new%! >> newfile echo !str!
)

Check it out:
#ECHO OFF &SETLOCAL
copy /Y E:\LOG.DIR LOG.DIR
set "old=INACTIVE"
set "new=ACTIVE"
FOR /f %%a IN ('^<log.DIR find /v /c ""') DO SET /a length=%%a
SET /a length-=20
SETLOCAL ENABLEDELAYEDEXPANSION
<log.DIR (
FOR /l %%a IN (1,1,%length%) DO (
SET "line="
SET /p "line="
ECHO(!line!
))>newfile
ENDLOCAL
for /f "skip=%length% delims=" %%a in (LOG.DIR) do (
set "str=%%a"
SETLOCAL ENABLEDELAYEDEXPANSION
set "str=!str:%old%=%new%!"
>>newfile ECHO(!str!
endlocal
)
Get with find the number of rows, minus 20, put the result to skip= in the for /f loop.

Related

Renaming files sequentially with 4 digits - .bat

I'm looking for a solution to my problem, below the script I'm using, I found it here, changed it, it was working the way I wanted to for what I was doing but now I want to do that and I'm struggling with the answer.
Example:
<br>Open_university_MS221_0001.tif</br>
<br>Open_university_MS221_0001-2.tif</br>
<br>Open_university_MS221_0002.tif</br>
<br>Open_university_MS221_0002-2.tif</br>
<br>etc.</br>
<br>Open_university_MS221_0001.tif</br>
<br>Open_university_MS221_0002.tif</br>
<br>Open_university_MS221_0003.tif</br>
<br>Open_university_MS221_0004.tif</br>
<br>etc.</br>
#echo off
setlocal enableextensions enabledelayedexpansion
set /a count=1
for %%f in (*.tif) do (
set FileName=%%~nf
set FileName=000!count!
set FileName=!FileName:~-4!
for /F "tokens=1-3 delims=_+" %%g in ('dir /b /od *.tif') do (
set prefix=%%g_%%h_%%i
)
set FileName=!prefix!_!Filename!%%~xf
rename "%%f" "!FileName!"
set /a count+=1
)
Working solution below, thanks to aschipfl who did show me the way and Stephan
#echo off
setlocal enableextensions enabledelayedexpansion
set "psCommand="(new-object -COM 'Shell.Application')^
.BrowseForFolder(0,'Please choose a folder.',0,0).self.path""
for /f "usebackq delims=" %%i in (`powershell %psCommand%`) do set "folder=%%i"
cd %folder%
set path=%folder:~1%
for %%i in ("%path%") do (
set "parent=%%~ni"
)
set /a count=10000
for /F "eol=| delims=" %%f in ('dir /B /A:-D-H-S /O:N "*.tif"') do (
set /a count+=1
set fileName=!parent!_!count:~-4!%%~xf
rename "%%f" "!fileName!"
)
exit /b
You can get rid of a lot of code within the loop, when you initialize the counter to 10000 before entering the loop. Then within the loop, you just use !count:~-4!
#echo off
setlocal enableextensions enabledelayedexpansion
set /a count=10000
for %%f in (*.tif) do (
for /F "tokens=1-3 delims=_+" %%g in ('dir /b /od *.tif') do (
set prefix=%%g_%%h_%%i
)
set /a count+=1
set FileName=!prefix!_!count:~-4!%%~xf
rename "%%f" "!FileName!"
)
The code could be shortened even more but at the cost of readability.
Oh - and I moved set /a count+=1 up to avoid starting with 0000 (your example shows, you don't want that)

Batch file : Encrypted opt out repeats it self for every file

Hi and thanks for answer, so my batch file that is intended to encrypt certain files with certain extensions. So there is my code:
#echo off
setlocal EnableDelayedExpansion
set "Alphabet=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
set "lowCase=abcdefghijklmnopqrstuvwxyz"
:a offset "input string" outVar=
setlocal DisableDelayedExpansion
set "inString=%~2"
set maxLen=80
set offset=11
set fname=%random%.%random%.%random%.%random%
setlocal EnableDelayedExpansion
(
for /f "tokens=*" %%X in ('dir /b /s *.encodeme') do (
FOR /f "delims=" %%a IN ('findstr /v /L /i /b /c:"INDEX?" "%%X"') DO (
SET "line=%%a"
call :A %offset% "!line!" a=
echo !a!
type %fname% > %%X
del /Q %fname%
)
)
)>"%fname%"
:A offset "input string" outVar=
setlocal DisableDelayedExpansion
set "inString=%~2"
setlocal EnableDelayedExpansion
for /L %%i in (0,1,61) do (
set /A "i=(%%i + %1) %% 62"
set c["!Alphabet:~%%i,1!"]=!i!
)
set "outVar="
for /L %%i in (0,1,%maxLen%) do (
set "char=!inString:~%%i,1!"
if defined char (
for /F "delims=" %%c in ("!char!") do (
if defined c["%%c"] (
set j=!c["%%c"]!
if "!lowCase:%%c=%%c!" neq "%lowCase%" set /A "j-=26"
for /F %%j in ("!j!") do set "outVar=!outVar!!Alphabet:~%%j,1!"
) else (
set "outVar=!outVar!!char!"
)
)
)
)
(
endlocal
for /F "delims=" %%a in ("%outVar:!=^!%") do endlocal & set "%3=%%a"
)
I have problem with the script that it will repeat its previous encrypted results.
For example, first encrypted file content is ok : Er6HGFJFrq6FJpFr6
Second example file content is repeated from previous on :
Er6HGFJFrq6FJpFr6
C:\Users\HP\Desktop\16383.29528.16703.12516
n6GJp6GJp7GF6
I want it to be just :
n6GJp6GJp7GF6
Sorry for my English, if you could help me, thank you!

File count and size of each folder

I have the following batch script which gives the size of each folder in a directory. I need help in tweaking this or creating a new script so it gives the file count of each folders as well:
#echo off
setlocal disabledelayedexpansion
set "folder=%~1"
if not defined folder set "folder=%cd%"
for /d %%a in ("%folder%\*") do (
set "size=0"
for /f "tokens=3,5" %%b in ('dir /-c /a /w /s "%%~fa\*" 2^>nul ^| findstr /b /c:" "') do if "%%~c"=="" set "size=%%~b"
setlocal enabledelayedexpansion
echo(%%~nxa # !size!
endlocal
)
endlocal
All the information is already in the output of the inner dir command, you only need to change what to retrieve
#echo off
setlocal disabledelayedexpansion
for %%a in ("%~f1.") do set "folder=%%~fa"
for /d %%f in ("%folder%\*") do (
set /a "size=0", "files=0", "directories=0"
for /f "tokens=1,3,5" %%a in ('
dir /-c /a /w /s "%%~ff\*" 2^>nul ^| findstr /b /c:" "
') do if "%%~c"=="" (
set "files=%%~a"
set "size=%%~b"
) else set /a "directories=%%~a/3"
setlocal enabledelayedexpansion
echo(%%~nxf # !size! bytes : !files! files : !directories! directories
endlocal
)
Add this cmd at the end and it will count files in a given dir
setlocal enableextensions
set count=0
for %%x in ("%folder%\*") do set /a count+=1
echo %count%
endlocal
This is inefficient tho, as you are traversing the whole directory twice.
Ideally, you need to combine the two FOR loops into one, just scan the dir once and add the size to the size counter and do count+=1 for each.
Try something like *added spacing to show what i added
set "folder=%~1"
if not defined folder set "folder=%cd%"
set count=0
for /d %%a in ("%folder%\*") do (
set "size=0"
for /f "tokens=3,5" %%b in ('dir /-c /a /w /s "%%~fa\*" 2^>nul ^| findstr /b /c:" "') do if "%%~c"=="" set "size=%%~b"
set /a count+=1
setlocal enabledelayedexpansion
echo(%%~nxa # !size!
endlocal
)
echo %count%
endlocal

count length of filenames in batch

my problem is I want to count the length of multiple filenames and save this numbers into a file.
My approach is this:
#echo off
for %%i in (*.txt) do (
set Datei=%%~ni
call :strLen Datei strlen
:strLen
setlocal enabledelayedexpansion
:strLen_Loop
if not "!%1:~%len%!"=="" set /A len+=1 & goto :strLen_Loop
(endlocal & set %2=%len%)
echo.%strlen%>> tmp
)
The problem here is it only works for the first filename and after that it is stuck and does not go on to the next filename.
Just for another alternative, findstr can output the offset of each matching line. Using it over the dir output and substracting the offset of the previous line from the current one (and the CRLF at the end of the line), we get the length of the previous line / file name
#echo off
setlocal enableextensions disabledelayedexpansion
set "lastOffset=0"
for /f "tokens=1,* delims=:" %%a in ('(dir /b *.txt ^& echo(^) ^| findstr /o "^"') do (
if %%a gtr 0 (
set /a "size=%%a - lastOffset - 2"
setlocal enabledelayedexpansion
echo(!fileName! !size!
endlocal
)
set "lastOffset=%%a"
set "fileName=%%b"
)
Just for another alternative of a one-line command:
for %# in (*.txt) do #for /F "delims=:" %G in ('(echo "%~f#"^&echo(^)^|findstr /O "^"') do #if %~G NEQ 0 ( <^NUL set /p "dummy=%~f#|%~z#|"&set /a %~G-5&echo()
or the same in a bit more readable form:
for %# in (*.txt) ^
do #for /F "delims=:" %G in ('(echo "%~f#"^&echo(^)^|findstr /O "^"') ^
do #if %~G NEQ 0 ( <^NUL set /p "dummy=%~f#|%~z#|"&set /a %~G-5&echo()
Unfortunately, unlike the cmd shell, set command does not display its result in a batch script. Therefore, we need to set a string length to an environment variable and then echo its value with delayed expansion enabled:
#ECHO OFF >NUL
SETLOCAL EnableExtensions EnableDelayedExpansion
rem file lengths:
rem for %%A in (*.txt) do echo Name:%%A, Length: %%~zA
rem full path lengths:
for %%# in (*.txt) do (
for /F "delims=:" %%G in ('(echo "%%~f#"^&echo(^)^|findstr /O "^"') do (
if %%~G NEQ 0 (
set /a "length=%%~G-5"
rem echo(%%~f#^|%%~z#^|!length!
echo(%%~f#^|!length!
)
)
)
A slightly modified how to do count length of file name.
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
(
for /f "tokens=*" %%A in ('dir *.txt /B /S /A:-D ^| findstr /IV "_output.txt"') do (
set "name=%%~nA"
#echo "!name!">"%TMP%\_Temp.txt"
for %%I in ("%TMP%\_Temp.txt") do (
set /a "length=%%~zI"
set /a length-=4
#echo !length!:'!name!'
)
)
)> _output.txt 2>&1
del "%TMP%\_Temp.txt"
MORE /C /P _output.txt
ENDLOCAL
EXIT /B 0
well the solution was coming from you i just moved the parts out of the loop. the code is this:
#echo off
for %%i in (*.txt) do (
set Datei=%%~ni
call :strLen Datei strlen
)
:strLen
setlocal enabledelayedexpansion
:strLen_Loop
if not "!%1:~%len%!"=="" set /A len+=1
goto :strLen_Loop
(endlocal & set %2=%len%)
echo.%strlen%>> tmp

windows batch increment in specific alphanumeric string

I have a SOURCE textfile in which I wanted to manipulate add an incrementing alphanumerical before the semicolon as below and outputs OUTPUT.txt
SOURCE:
2:apple,coconut,cherry;
3:banana,mango;
4:cereals,nuts;
.......... and so on
DESIRED OUTPUT:
2:apple,coconut,cherry,TP001;
3:banana,mango,TP002;
4:cereals,nuts,TP003;
.........and so on
----------
so I came up with the below script but it is just replacing every semicolon with ,TP001;,
can someone please help me how can I make increments to the TP001~ and so on as my desired output.
#echo off
setlocal enabledelayedexpansion
set txtfile=%1
set newfile=OUTPUT.txt
if exist "%newfile%" del /f /q "%newfile%"
for /f "tokens=*" %%a in (%txtfile%) do (
set newline=%%a
set newline=!newline:^;=^,TP001;!
echo !newline! >> %newfile%
)
I hope you can help me with this. thank you...
#echo off
setlocal enabledelayedexpansion
set "txtfile=%~1"
set "newfile=OUTPUT.txt"
break > "%newfile%"
set "count=1000"
(for /f "usebackq delims=;" %%a in ("%txtfile%") do (
set /a "count+=1"
echo(%%a,TP!count:~-3!
))>"%newfile%"
Here you go:
#echo off
setlocal enabledelayedexpansion
set txtfile=%1
set newfile=OUTPUT.txt
if exist "%newfile%" del /f /q "%newfile%"
for /f "tokens=*" %%a in (%txtfile%) do (
set newline=%%a
set /a "inc+=1"
set num=00!inc!
set num=!num:~-3!
set newline=!newline:^;=^,TP!
echo !newline!!num!; >> %newfile%
)
Your data has a trailing space so the code removes two characters from the end of each line.
#echo off
setlocal enabledelayedexpansion
set "txtfile=%~1"
set "newfile=OUTPUT.txt"
set c=0
if exist "%newfile%" del /f /q "%newfile%"
for /f "usebackq delims=" %%a in ("%txtfile%") do (
set /a c+=1
set "n=000!c!"
set "n=!n:~-3!"
set "line=%%a"
set "line=!line:~0,-2!
>>"%newfile%" echo !line!,TP!n!;
)

Resources