Batch file for reading the first line of text that has not been used, and then mark as used

I have a requirement to read the first available line from a text file in a Windows batch file, pass it to a variable, and mark the name \ line as used

The following is an example file.

an Apple
pear
Orange

the script will start with "apple", pass "apple" into a variable that will be used later in the script (I know how to make this bit), and then write this line to read & apple, '&' works like a marker to say that it was used.

The file will look like this:

& an Apple
pear
Orange

the next time the batch file is launched, it will take the "pear", pass it to a variable and mark it a and do it like this:

& an Apple
& Amp; pear
Orange

I started by trying to find '&' and then trying to move to the next line, but I fail about 12 hours after the attempt. This is what I got so far .. not much:

for / f "tokens = 1"% l in ('name.txt') do (Find / v "&" / v "^ ---- ^ $") (for / F% n in (% l) do (set NewName =% n))

thanks

+4
source share
2 answers

Doing this on the.file will change each line in turn;

 @echo off setlocal enabledelayedexpansion type nul > the.file.temp set last= for /F "tokens=*" %%A in (the.file) do ( set line=%%A if "!line:~0,1!" neq "&" if "!last!" equ "" ( set last=!line! set line=^&!line! ) echo !line! >> the.file.temp ) echo last value is !last! type the.file.temp > the.file 

(If the line does not start with & , and the last variable is empty, put the line in last and change line to leading & . Always add line to temp file, rename when finished)

+6
source

Alex k. has a good answer, which is probably suitable for most situations. (I supported.)

However, this will damage any text containing ! . This limitation can be fixed by turning the delay on and off within the cycle.

The solution is likely to be fast enough for the largest file sizes. But the FOR loop can become quite slow for large files.

I tested a 190KB file containing 2817 lines, and Alex K.'s solution took 20 seconds for one run.

Here is a completely different solution without using any cycles that process the same 190 KB file in 0.07 seconds - 285 times faster :)

 @echo off setlocal enableDelayedExpansion set "file=test.txt" findstr /bv "$ &" "%file%" >"%file%.available" set "var=" <"%file%.available" set /p "var=" if defined var ( >"%file%.new" ( findstr /b "&" "%file%" <nul set /p "=&" type "%file%.available" ) move /y "%file%.new" "%file%" >nul ) del "%file%.available" echo var=!var! 


Update:. As requested in the commentary, a heavily commented version of the code is presented here.

 @echo off setlocal enableDelayedExpansion :: Define the file to process set "file=test.txt" :: Write the unused lines to a temporary "available" file. We don't want any :: empty lines, so I strip them out here. There are two regex search strings; :: the first looks for empty lines, the second for lines starting with &. :: The /v option means only write lines that don't match either search string. findstr /bv "$ &" "%file%" >"%file%.available" :: Read the first available line into a variable set "var=" <"%file%.available" set /p "var=" :: If var defined, then continue, else we are done if defined var ( REM Redirect output to a "new" file. It is more efficient to redirect REM the entire block once than it is to redirect each command individulally >"%file%.new" ( REM Write the already used lines to the "new" file findstr /b "&" "%file%" REM Append the & without a new line <nul set /p "=&" REM Append the unused lines from the "available" file. The first appended REM line is marked as used because of the previously written & type "%file%.available" ) REM Replace the original file with the "new" content move /y "%file%.new" "%file%" >nul ) :: Delete the temp "available" file del "%file%.available" :: Display the result echo var=!var! 


I did not test this, but I just realized that I could write a line that writes available lines to look for lines starting with a character other than & :

 findstr "^[^&]" "%file%" >"%file%.available" 
+3
source

Source: https://habr.com/ru/post/1444836/


All Articles