my input file named done.txt as per below.
clip_id HCQLR01HM01AO
clip_id HAUGL01HM01AC
clip_id HEBQC01HM01CD
clip_id HEFCD01HM01AK
clip_id HBYVA01HM01CY
clip_id HCFJI01HM01AI
And i want to extract last 12 char and write into new text file with name res.txt
this is my coding. but this only works for 1st line. How to loop it for 2nd,3rd and 4th lines?
#echo off
setlocal enabledelayedexpansion
for /f "tokens=*" %%a in (C:\Users\administrator\Desktop\com\done.txt) do (
set line=%%a
set chars=!line:~-13,12!
echo !chars! > res.txt
)
pause
many thanks
The single ">" in echo !chars! > res.txt overwrites res.txt each time. Change this line to echo !chars! >> res.txt
You might also want to remove res.txt before the loop, resulting in:
#echo off
setlocal enabledelayedexpansion
del res.txt
for /f "tokens=*" %%a in (C:\Users\administrator\Desktop\com\done.txt) do (
set line=%%a
set chars=!line:~-13,12!
echo !chars! >> res.txt
)
pause
Related
I'd like to write a batch script that reads a specific word between delimiters:
Eg my text file contains the below
!DATA
Scen|2022|m|YTD|a|b|c|d|e|f|g|h|101
Scen|2022|m|YTD|a1|b1|c1|d1|e1|f1|g1|h1|102
The text file will have around 1000 lines. I will always want to read the 3rd line.
I want to:
1. Get the first word before the pipe delimiter (eg Scen) and store to some variable
2. I then want the second word between 1st & 2nd pipe marks (eg 2022)
Any help in this would be great.
Here's an example for you to really get your teeth into:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "targetLine="
( Set /P "="
Set /P "="
Set /P "targetLine="
) 0< "textFile.ext"
If Not Defined targetLine GoTo :EOF
For /F "Delims==" %%G In ('"(Set Field) 2>NUL"') Do Set "%%G="
Set "i=1"
SetLocal EnableDelayedExpansion
Set "Field!i!=%targetLine:|=" & Set /A i +=1 & Set "Field!i!=%"
Echo %%Field1%% = %Field1%; %%Field2%% = %Field2%
Pause
The above technique has actually defined a variable for each of the pipe delimited fields. To see those just change line 13 to (Set Field) 2>NUL
(Set /P "var=") 0< "stdInput" defines var with the value of the first non empty input line, In this case you would change stdInput (textfile.ext) to your actual source file. I have therefore extended the idea to retrieve the third line. I will not explain the creation of the variables for each of the fields, simply link you to an already existing explanation.
If these are your intended executions:
!DATA // Your Line Skipped: 1
Scen|2022|m|YTD|a|b|c|d|e|f|g|h|101 // Your Line Skipped: 2
Scen|2022|m|YTD|a1|b1|c1|d1|e1|f1|g1|h1|102 // Your Line Strings To Save: Scen & 2022
... // Your Lines Remaining Skipped: Goto %:^)
A simpler way to do it would be:
#echo off & cd /d "%~dp0"
for /f "usebackq skip=2 delims=| tokens=1-2*" %%i in (`
type InputFile.txt`)do set "_str_1=%%i" && set "_str_2=%%j" & goto %:^)
%:^)
echo\ %%_str_1%% == %_str_1% && echo\ %%_str_2%% == %_str_2%
Another, perhaps simpler, method:
#echo off
setlocal EnableDelayedExpansion
rem Read the 3rd line
( for /L %%i in (1,1,3) do set /P "line3=" ) < test.txt
rem Get 1st and 2nd words from line 3
set "goto="
set "word1=%line3:|=" & !goto! & set "goto=goto continue" & set "word2=%"
:continue
echo word1="%word1%", word2="%word2%"
I have a text file that I would like to edit and therefore would like to remove the last line. I have the following code for this:
for /f "delims=" %%a in (input.txt) do (
echo/|set /p ="%%a%"
)>>output.txt
input:
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
output:
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
Now I would like to edit the data in groups for example by the first value, so that I have the following output:
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
If I replace the FOR /F "delims=" %%a in (input.txt) do … loop with an equivalent FOR %%a in … loop:
#ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion
set "_gruppeName="
(
for %%a in (
"GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
) do (
for /f "tokens=1 delims=;" %%A in ("%%~a") do (
if /I NOT "%%~A"=="!_gruppeName!" (
if defined _gruppeName echo(
set "_gruppeName=%%~A"
)
)
echo/|set /p ="%%~a"
)
echo(
)>>output.txt
REM debugging output follows
type output.txt
Output:
1st run: 2>NUL del output.txt & D:\bat\CR\61816520.bat
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
Next run: D:\bat\CR\61816520.bat
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
Your question is not clear
based on ... the first value (GRUPPEA)
is it SORTed? or just write duplicates on the same line?
#echo off
SETLOCAL EnableExtensions EnableDelayedExpansion
::VARIABLES
set "in=input.txt" IN file
set "out=output.txt" OUT file
set/a"#lines=0"
set "gruppe="
set "prevContent="
::Count lines
FOR /F %%L in ('
"findstr /N "^^" "%in%" %= do not skip empty lines =%"
') do set/a"#lines+=1" %= Get the # of lines =%
::Read IN via SET /P #LINES number of times
::Bangs (!) will be lost
<"%in%" >"%out%" (FOR /L %%# in (1 1 %#lines%) do (
set "data=" ::clear DATA
set/p"data=" ::read from IN
FOR /F tokens^=1^ delims^=^;^ eol^= %%T in ("!data!") do set "gruppe=%%T"
if NOT "!prevContent!" == "!gruppe!" (
set "prevContent=!gruppe!"
echo(
)
<nul set/p"=!data!" ::does not work with leading space, tabs, or equal signs
)) %= read file by lines via SET /P =%
exit /b
The script counts the number of lines using FINDSTR /N and a FOR /F loop to count the # of lines, which is required to execute SET /P that many times.
Tips:
Use ECHO( instead of the problematic ECHO.
Using a pipe | is very slow, as described by #jeb here. Use <nul instead
I have been given this txt file ej:
-state;of;product-;-201705-;-ID1-;-SOLD-;-4-;-PROD;1-;;
and i need to change it to:
-state of product-;-201705-;-ID1-;-SOLD-;-4-;-PROD 1-;;
As you can see every two - I need to change ; with an space.
Can you help me?
#echo off
setlocal enabledelayedexpansion
for /f "delims=" %%a in (YOURFILENAME.TXT) do (
SET s=%%a
SET s=!s:;= !
SET s=!s:- =-;;!
SET s=!s: -=-!
SET s=!s:-;;-=-;-!
echo !s!
)
will echo -state of product-;-201705-;-ID1-;-SOLD-;-4-;-PROD 1-;;
if you want to write each modified line back to a file, then just echo it to file.
#echo off
setlocal enabledelayedexpansion
for /f "delims=" %%a in (YOURFILENAME.TXT) do (
SET s=%%a
SET s=!s:;= !
SET s=!s:- =-;;!
SET s=!s: -=-!
SET s=!s:-;;-=-;-!
echo !s!
) >> NewFile.txt
You need to copy the above script, paste in txtfile then rename the file as mybatch.cmd or mybatch.bat Change the MYFILENAME.TXT in the script to the name of your txt file where the lines -state;of;product-;-201705-;-ID1-;-SOLD-;-4-;-PROD;1-;; place the mybatch in the same directory as this file. double click the mybatch file. Once it is done, there will be a file called NewFile.txt which will contain the edited text.
Ok, forget about the above for now. on your PC open cmd.exe then copy everything below and then right click and paste into cmd.exe window. It will create a file for you in economic_changes called MyBatch.cmd double click and wait for it to finish. Now see file New_economic_changes.txt in the directory.
echo #echo off > "%userprofile%\desktop\Economic_Folder\MyBatch.cmd"
echo setlocal enabledelayedexpansion >> "%userprofile%\desktop\Economic_Folder\MyBatch.cmd"
echo for /f "delims=" %%a in (economic_changes.txt) do ( >> "%userprofile%\desktop\Economic_Folder\MyBatch.cmd"
echo SET s=%%a >> "%userprofile%\desktop\Economic_Folder\MyBatch.cmd"
echo SET s=!s:;= ! >> "%userprofile%\desktop\Economic_Folder\MyBatch.cmd"
echo SET s=!s:- =-;;! >> "%userprofile%\desktop\Economic_Folder\MyBatch.cmd"
echo SET s=!s: -=-! >> "%userprofile%\desktop\Economic_Folder\MyBatch.cmd"
echo SET s=!s:-;;-=-;-! >> "%userprofile%\desktop\Economic_Folder\MyBatch.cmd"
echo echo !s! >> "%userprofile%\desktop\Economic_Folder\MyBatch.cmd"
echo ) >> "%userprofile%\desktop\Economic_Folder\New_economic_changes.txt" >> "%userprofile%\desktop\Economic_Folder\MyBatch.cmd"
pause
What about this?
#echo off
setlocal EnableDelayedExpansion
set "STRING=-state;of;product-;-201705-;-ID1-;-SOLD-;-4-;-PROD;1-;;"
echo original: !STRING!
rem // Replace every `-` by `"`, enclose whole string in `""`:
set ^"STRING="!STRING:-="!"" & rem/ odd number of " deranges syntax highlighting!
rem /* Let a `for` loop dismantle the string; since `;` is a token separator
rem (like ` `, `,`, `=`), the loop divides the string at that characters;
rem every token separator that appears in a pair of `""` is maintained;
rem the string portions are reassembled, separated by spaces: */
set "RETURN= "
for %%I in (!STRING!) do set "RETURN=!RETURN!%%I "
rem // Remove surrounding `""` as well as leading and trailing space:
set "RETURN=!RETURN:~2,-2!"
rem // Replace every `"` by `-`:
set ^"RETURN=!RETURN:"=-!" & rem/ odd number of " deranges syntax highlighting!
echo modified: !RETURN!
endlocal
I use this batch files to create a list of files
#echo off
(for /f "delims=" %%a in ('dir/b/a-d *.tex') do echo %%a,)>liste.dat
the result is like this
file1.tex,
file2.tex,
file3.tex,
...
lastfile.tex,
how do I delete the last comma?
#echo off
SETLOCAL EnableDelayedExpansion
SET "in="
(
for %%a in (*.tex) do (
IF "!in!"=="" (
set in=%%a
) ELSE (
echo !in!,
set in=%%a
)
)
echo !in!
)>liste.dat
#echo off
setlocal EnableDelayedExpansion
set "comma="
< NUL (
for %%a in (*.tex) do (
set /P "=!comma!%%a"
set comma=,^
%Empty line%
)
echo/
) > liste.dat
EDIT: Reply to a comment
Ops! When I was developing this code I just displayed the output in the screen, where it looks correct:
C:\> test.bat
One.tex,
Three.tex,
Two.tex
Even if the output is sent to a file and the file is displayed in the screen, the output looks correct:
C:\> test.bat > output.txt
C:\> type output.txt
One.tex,
Three.tex,
Two.tex
However, the character inserted after each comma is just a LF so if this file is open with Notepad, the LF's are not converted to "end of lines"; just cmd.exe screen output converts LF to CR+LF pair ("cooked output" instead of "raw output").
The way to fix this detail is inserting a complete CR+LF pair after each comma:
#echo off
setlocal EnableDelayedExpansion
for /F %%a in ('copy /Z "%~F0" NUL') do set "CR=%%a"
set "comma="
< NUL (
for %%a in (*.tex) do (
set /P "=!comma!%%a"
set comma=,!CR!^
%Empty line%
)
echo/
) > liste.dat
The problem is that you don't know how many lines/files there will be. So you'll have to use two loops the way your code is written. One to count the lines and one to perform the operations. It's way easier to have a different handling for the first line instead of the last one. So how about this:
#echo off
SETLOCAL EnableDelayedExpansion
SET /a i=0
(for /f "delims=" %%a in ('dir /b/a-d *.tex') do (
IF !i!==1 (
echo ,%%a
) ELSE (
ECHO %%a
SET /a i=1
)
)
)>liste.txt
This will generate something like this:
file1.tex
,file2.tex
,file3.tex
...
,lastfile.tex
This seems equivalent to your desired output. If you actually want to have , at the end of the lines instead of at the beginning of the next one, tell me and I'll update the code but it'll be quite ugly.
I have a simple text file with numbers like:
12345
45678
34567
89101
I need a batch that will return the nth line from this file. n should be taken from a command line argument.
I am very new to batch scripting so Thanks in advance for any help on this.
To get the file from the nth line you could use more +n (For line1 is n=0).
To split the rest of the file you could use a FOR /F loop.
This works even, if there are empty lines before the nth line.
It could be necessary to set the EOL to an unused character or to linefeed (default is ;)
set "lineNr=%1"
set /a lineNr-=1
for /f "usebackq delims=" %%a in (`more +%lineNr% text.txt`) DO (
echo %%a
goto :leave
)
:leave
You can use batch file extension.
token.bat
#echo off
setlocal ENABLEDELAYEDEXPANSION
set l=%1
set c=0
for /f "delims=" %%1 in ('type foo.txt') do (
set /a c+=1 && if "!c!" equ "%l%" echo %%1%
)
If you have a file like following,
foo.txt
AAAA
BBBB
CCCC
DDDD
And specify line number like following
token 3
You'll get
CCCC
You could use FOR /F with the skip parameter:
#ECHO OFF
SET skip=%1
SET /A skip-=1
IF %skip% LSS 0 GOTO out
IF %skip% GTR 0 SET params="skip=%skip%"
FOR /F %params% %%L IN (filename) DO (SET "line=%%L"& GOTO out)
:out
ECHO %line%
The skip parameter means the FOR /F loop must skip the specified number of lines at the beginning. The parameter is only applied if you specify a line number greater than 1. If you specify a number less than one or a non-number, the script outputs an empty string.
+1 for Jeb's solution... I did not realize you could use the more command to skip lines like that!
Here is an alternate method that I use for getting a specific line from a file (or from the multi-line output of another program):
#echo off
for /f "tokens=1* delims=:" %%a in ('findstr /n .* "C:\SomeFile.txt"') do (
if "%%a" equ "%1" echo.%%b
)
I use findstr /n .* "Path\FileName.ext" to add line numbers, and to ensure no empty lines are skipped by the for loop.
I then set "tokens=1* delims=:" to separate the line numbers from the line content.
Finally, I compare the current line number (%%a) with the line specified by the %1 parameter, and echo the line contents (%%b) on a match.
To Find Nth to Mth Character In Line No. L --- Example For Finding Label
#echo off
REM Next line = Set command value to a file OR Just Choose Your File By Skipping The Line
vol E: > %temp%\justtmp.txt
REM Vol E: = Find Volume Lable Of Drive E
REM Next Line to choose line line no. +0 = line no. 1
for /f "usebackq delims=" %%a in (`more +0 %temp%\justtmp.txt`) DO (set findstringline=%%a& goto :nextstep)
:nextstep
REM Next line to read nth to mth Character here 22th Character to 40th Character
set result=%findstringline:~22,40%
echo %result%
pause
exit /b
Save as find label.cmd
The Result Will Be Your Drive E Label
Enjoy
Based off of Amit's Answer, I made a utility called snip.cmd.
USAGE: snip FILE LINE FIRSTCHARACTER LASTCHARACTER
example:
foo.txt
//
// File Checksum Integrity Verifier version 2.05.
//
77752e4c91ba96dcc6c2bb4bdcdbdec5 c:\users\lapinot\desktop\token.bat
snip foo.txt 3 0 33 will yield 77752e4c91ba96dcc6c2bb4bdcdbdec5
Here is my code for snipe.cmd (you can add snipe to your command line by copying snip.cmd to c:\Windows\System32):
#echo off
:: USAGE
:: snip <file> [Line - Starts at 0] [First Column - Start Count at 0] [Last Colum]
set file=%1
set line=%2
set char1=%3
set char2=%4
for /f "usebackq delims=" %%a in (`more +%line% %file%`) DO (set findstringline=%%a& goto :nextstep)
:nextstep
echo echo %%findstringline:^~%char1%,%char2%%% > %temp%\result.bat
%temp%\result.bat
del %temp%\result.bat
:EOF
exit /b
echo "enter the line number.."; read i; awk 'NR==$i' <file_name>;