Home > Blockchain >  Bat file that copy text.files after applying 2 filters
Bat file that copy text.files after applying 2 filters

Time:11-24

I'm a biologist, with no coding knowledge, trying to create a script that reads every *rprt.txt file in a folder.

In line 11 of each file, the fifth word is a number, If that number is 6000<number<14000 then I want to read the fifth word in line 13 and if that number is greater than 600. Copy the file into another folder in that directory.

At this point I've tried a lot of things. I know the next code is exiting the loop but is the best I got.

@echo off
for %%f in (*rprt.txt) do set "name=%%f" &goto first

:first
for /F "skip=10 tokens=5" %%i in (%name%) do set "var1=%%i" &goto nextline

:nextline
for /F "skip=12 tokens=5" %%i in (%name%) do set "var2=%%i" &goto nextline2

:nextline2
if %var1% geq 6000 (if %var2% geq 600 echo.%name% >> valid.txt)

I've also tried this to test the for loop but I don't understand what's wrong. This prints "echo is off" 3 times

@echo off
for %%f in (*rprt.txt) do (set "name=%%f" & echo %name% >> valid.txt)

CodePudding user response:

You were definitely on the right track, but the code for validating that something is a number can get kinda weird if you're not used to seeing it (in this case, I remove everything that isn't a digit and then return 1 if there's anything remaining) and the way that GTR and LSS work can also be confusing since it's based on ASCII values so words report as greater than numbers.

The script expects the reports to be in their own folder and the output folder to be in its own folder, and both of these folders should be in the same folder as the script, as opposed to the script being in the same folder as the input files.


@echo off
setlocal enabledelayedexpansion

set "input_directory=%~dp0\input"
set "output_directory=%~dp0\output"

pushd "%input_directory%"
for %%A in (*_rprt.txt) do (
    for /f "tokens=5" %%B in ('findstr /n /r "^" "%%~A" ^| findstr "11:"') do set "line_11_num=%%B"
    for /f "tokens=5" %%B in ('findstr /n /r "^" "%%~A" ^| findstr "13:"') do set "line_13_num=%%B"
    
    call :isNumber !line_11_num! n[11]
    call :isNumber !line_13_num! n[13]
    set /a "valid_report=!n[11]! !n[13]!"
    
    if "!valid_report!"=="0" (
        if !line_11_num! GTR 6000 if !line_11_num! LSS 14000 (
            if !line_13_num! GTR 600 (
                    copy "%%~A" "%output_directory%"
            )
        )
    )
)
exit /b

::------------------------------------------------------------------------------
:: Determines if a given string is a positive integer
::
:: Arguments: %1 - The value to check
::            %2 - The variable to store the result in
:: Returns:   0 if the number is a positive integer, 1 otherwise
::------------------------------------------------------------------------------
:isNumber
set "is_number=0"
for /f "delims=0123456789" %%A in ("%~1") do set "is_number=1"
set "%~2=%is_number%"
exit /b

CodePudding user response:

@ECHO OFF
SETLOCAL
rem The following settings for the directories and filenames are names
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.

SET "sourcedir=u:\your files"
SET "destdir=u:\your results"

FOR %%e IN ("%sourcedir%\*rprt.txt") DO (
 rem %%e has filename
 SET "line11="
 FOR /f "usebackqskip=10tokens=5" %%y IN ("%%e") DO IF NOT DEFINED line11 (
  SET "line11=y"
  SET "line13="
  FOR /f "usebackqskip=12tokens=5" %%o IN ("%%e") DO IF NOT DEFINED line13 (
   SET "line13=y"
   IF %%y gtr 6000 IF %%y lss 14000 IF %%o gtr 600 ECHO COPY "%%e" "           
  • Related