J'ai un répertoire de milliers de fichiers texte qui commencent par tape * (ce sont des fichiers de sortie d'un ancien programme Fortran) et j'ai besoin d'extraire 4 lignes de chaque fichier ainsi que le nom de fichier dont ils ont été extraits. Les 4 lignes commencent 4 lignes vers le bas à partir d'une chaîne prévisible, mais nous pouvons utiliser "Header" pour cet exemple:

Tape1:

First line
...
Header
Trash1
Trash2
Trash3
Data1
Data2
Data3 
Data4 
...

Je ne me soucie de rien avant ou après ces 4 lignes de données, mais je veux aussi que le nom de fichier (c'est-à-dire "tape1") s'affiche après chaque ligne de données, comme ceci:

Data1 tape1
Data2 tape1 
Data3 tape1 
Data4 tape1
Data5 tape2
Data6 tape2 
...

Des idées sur un fichier batch Windows facile à faire sur tous les fichiers bande * dans un répertoire?

1
mst3kzz 20 avril 2017 à 02:33

3 réponses

Meilleure réponse
@echo off
cls
rem get a list of file names sorted alphabetically by name
dir /b tape* /ON>.\Files.txt

rem delete any existing output from any previous run
if exist .\FoundData.txt del .\FoundData.txt

SET DataFileName=
SET LineData=
SET FoundData=

SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F %%A IN (.\Files.txt) DO (
    SET DataFileName=%%A

    FOR /F "tokens=1,2* " %%B IN (!DataFileName!) DO (
        rem use the following line to get just the first word on the line 
        rem SET LineData=%%B

        rem use the following line to get the entire line
        SET LineData=%%B %%C %%D

        rem determine if the line contains "DATA" (case insensitive) and if so capture it
        if "%FoundData%"=="" ( ECHO !LineData!|FIND /I "DATA">Nul && (SET FoundData=!LineData! ) || (SET FoundData=) )

        rem if the line contained the data we want output it to the output file
        IF NOT "!FoundData!"=="" ( 
            (ECHO !FoundData! !DataFileName!>>.\FoundData.txt) 
        )
    )
    SET LineData=
    SET FoundData=
)
set DataFileName=
)
ENDLOCAL
if not exist .\FoundData.txt echo No data found>.\FoundData.txt
start notepad .\FoundData.txt  
0
thx1138v2 20 avril 2017 à 01:55

Vous pouvez essayer ce qui suit:

@echo off
for %%F in (".\tape*.txt") do (
    for /F "delims=:" %%N in ('findstr /N /X /C:"Header" "%%~F"') do (
        call :SUB "%%~F" %%N
    )
)
exit /B

:SUB
set /A "SKIP=%~2+3"
for /F "skip=%SKIP% usebackq delims=" %%L in ("%~1") do (
    echo(%%L %~n1
)
exit /B

Voici une approche alternative:

@echo off
for %%F in (".\tape*.txt") do (
    for /F %%C in ('^< "%%~F" find /C /V ""') do (
        set /A "POS=0" & set "NAME=%%~nF"
        < "%%~F" (
            setlocal EnableDelayedExpansion
            for /L %%I in (1,1,%%C) do (
                set "LINE=" & set /P LINE=""
                if "!LINE!"=="Header" (
                    set /A "POS=%%I+3"
                )
                if !POS! GTR 0 if %%I GTR !POS! (
                    echo(!LINE! !NAME!
                )
            )
            endlocal
        )
    )
)
0
aschipfl 20 avril 2017 à 00:21
@echo off
setlocal EnableDelayedExpansion

for /F "tokens=1,2 delims=:" %%a in ('findstr /N "Header" tape*') do (
   (for /L %%i in (-2,1,%%b) do set /P "="
    for /L %%i in (1,1,4) do set /P "line=" & echo !line! %%a
   ) < "%%a"
)
3
Aacini 20 avril 2017 à 04:03