0

I'm trying to edit a txt file by removing certain line numbers from it. i would like to search for all files in the folder containing .txt, remove some lines and than save the file using the inputfilename with -edit.txt

like: input.txt > input-edit.txt.

this is what i have at the moment:

@echo off (for /f "tokens=1,* delims=[]" %%a in ('type *.txt^|find /v /n ""') do (
echo/|findstr /x "34 35 36 37 38 39 40 41 42 43 80 81 82 83 84 85 86 87 88 89" >nul || echo/%%b
))>%%~na-edit.txt  

But the filename that's created is %~na-edit.txt

Can anyone help me?

Thanks!

2 Answers 2

0

Here's a quick example of how I might consider doing it. Just replace the name test, (the source directory), on line 4, and optionally the extension for the source files, (replacing .txt), on line 5. I used a relative source directory name, but you can use . for the current directory, or an absolute path too.

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion

Set "DirPath=test"
Set "FileExt=.txt"

For /F "Delims=" %%G In ('(Set "PathExt="^) ^& %SystemRoot%\System32\where.exe
 "%DirPath%":"*%FileExt%" 2^>NUL ^| %SystemRoot%\System32\findstr.exe /VRI
 "\-edit.txt$"') Do If Not Exist "%%~dpnG-edit%%~xG" (
    For /F "Delims=" %%H In ('%SystemRoot%\System32\findstr.exe /RN "$" "%%G" ^|
     %SystemRoot%\System32\findstr.exe /VR /C:"^3[456789]:" /C:"^4[0123]:"
     /C:"^8[0123456789]:"') Do (Set "_=%%H"
        SetLocal EnableDelayedExpansion
        Echo(!_:*:=!
        EndLocal)) 1>"%%~dpnG-edit%%~xG"

I have added some code to prevent parsing or overwriting existing -edit files, to ignore 8.3 naming for the target file extensions, and to ensure that empty lines are maintained, as well as not adding leading or trailing spaces to those lines. Additionally this method should not ignore any lines beginning with ;, and should not omit leading characters, (particularly : or ]), and any ! characters should also be maintained.

Please note that I decided, due to your example code to use the range abilities of findstr.exe, but I suppose for less specific patterns you could probably use, for example, /VR "^21: ^35: ^78:".

I should mention, as with almost everything I submit here, this is completely untested.

2
  • Note: I split both For command lines above, into three lines each, for readability. You are free to join those back into single lines, should you be happy to have super long lines in your own script.
    – Compo
    Commented May 26 at 22:46
  • Thank you for your answer, both you and Magoo's answer work great! but i don't know which one to accept as an good answer because both are working...
    – Desz5
    Commented May 27 at 18:47
0

What your code does is:
concatenate every .txt file and number each line
tokenise to line number in %%a and line contents in %%b
echo an empty line into findstr and attempt to find the numbers, discarding the result
If the line number was not found, echo the line contents
then attempt to write any output to the filename.

So - there's no need to try to fit all of this on one line - here's the more conventional layout:

@echo off
(
 for /f "tokens=1,* delims=[]" %%a in ('type *.txt^|find /v /n ""') do (
  echo/|findstr /x "34 35 36 37 38 39 40 41 42 43 80 81 82 83 84 85 86 87 88 89" >nul || echo/%%b
 )
)>%%~na-edit.txt 

Since %%a is outside of the for loop, %%a is not in-context, so %%~na-edit.txt is parsed as %%=>% and the remaining characters have no special meaning, hence %~na-edit.txt.

Even had the apparent intention worked, %%a is the line number, not the filename.

Further, since there is no & to separate @echo off from the remainder, the effective code is

@echo off>%%~na-edit.txt

since anything beyond off is discarded.

The resultant output of the find would be

[1]line 1 of file 1
…
[41]line 41 of file 1
[42]line 1 of file 2
…

Here's an UNTESTED idea

@echo off
setlocal
for /f "delims=" %%e in ('dir /b /a-d *.txt') do (
 (
  for /f "tokens=1*delims=[]" %%b in ('find /v /n "" ^<"%%e"') do (
   echo %%b|findstr /x "34 35 36 37 38 39 40 41 42 43 80 81 82 83 84 85 86 87 88 89">nul||echo/%%c
  )
 )>"%%~ne-edit.txt"
)

Note again this is UNTESTED

To explain:

It's normal to insert a setlocal flavour to ensure the environment is not corrupted by executing the batch.

Perform a dir command to list the directory of *.txt files in /b basic form (names only) /a-d without directory names.

This builds a list of filenames in memory, each is assigned to %%e in turn, so the source filename is in %%e. The delims= ensures the entire filename is assigned to %%e, even if it contains a separator like Space. Also, this list is built before the output files are generated, so the output filenames will not be included in the list (but would be if type *.txt was used)

Number each line in the file %%e, and tokenise to %%b and %%c using []. File is read using ^< else the filename will be reported by find before the listing of the numbered lines. The redirector needs to be escaped so that cmd assigns it to the find command instead of the for (which would generate a syntax error).

echo the line number in %%b to the findstr and if there's no exact match, echo the line contents. Although %%c will never be empty (which would be for an empty source line in this case & for /f skips empty lines), the echo/ variant of echo would generate an empty line instead of an echo status report.

Note that the syntax

(
 for…(
 …
 )
)>"filename"

will gather the output between the first ( and last ) and create a new file

The filename is quoted to ensure that filenames containing separators are correctly processed.

I prefer to avoid ADFNPSTXZ (in either case) as metavariables (loop-control variables) 
ADFNPSTXZ are also metavariable-modifiers which can lead to difficult-to-find bugs 
(See `for/f` from the prompt for documentation)

Note that should a filename whatever-edit.txt exist when this batch is executed, a file whatever-edit-edit.txt will likely appear.

6
  • Thank you for your time and knowledge! Sadly the output file is empty. it echoes all the lines like: FINDSTR: Cannot open, with the linenumbers.
    – Desz5
    Commented May 26 at 14:32
  • i've tried to use your solution from this post stackoverflow.com/questions/43616954/… and i think this is close to what may help but i can't get it to work.
    – Desz5
    Commented May 26 at 14:45
  • @Desz5, there was a typographic error in the FindStr command, which I have corrected, (I hope that's okay Magoo). Please try again.
    – Compo
    Commented May 26 at 19:39
  • @Compo : Good catch. Since I'm at a loose end, I'll try testing it...
    – Magoo
    Commented May 26 at 19:44
  • Now tested. Note changes - escaped redirector to make find not report the filename before output and echo/ to suppress echo status message if argument is empty.
    – Magoo
    Commented May 26 at 20:36

Not the answer you're looking for? Browse other questions tagged or ask your own question.