Windows 批处理文件以在字符串匹配后输出行,文件名
我有一个包含数千个以tape*开头的文本文件的目录(它们是一个旧Fortran程序的输出文件),我需要从每个文件以及从中提取它们的文件名中提取4行。这4行从一个可预测的字符串开始向下4行,但我们可以在本例中使用“Header”: 录音带1:Windows 批处理文件以在字符串匹配后输出行,文件名,windows,batch-file,cmd,Windows,Batch File,Cmd,我有一个包含数千个以tape*开头的文本文件的目录(它们是一个旧Fortran程序的输出文件),我需要从每个文件以及从中提取它们的文件名中提取4行。这4行从一个可预测的字符串开始向下4行,但我们可以在本例中使用“Header”: 录音带1: First line ... Header Trash1 Trash2 Trash3 Data1 Data2 Data3 Data4 ... 我不关心这4个数据行之前或之后的任何内容,但我还希望在每个数据行之后输出文件名(即“tape1”),如下所示:
First line
...
Header
Trash1
Trash2
Trash3
Data1
Data2
Data3
Data4
...
我不关心这4个数据行之前或之后的任何内容,但我还希望在每个数据行之后输出文件名(即“tape1”),如下所示:
Data1 tape1
Data2 tape1
Data3 tape1
Data4 tape1
Data5 tape2
Data6 tape2
...
有没有想过使用简易Windows批处理文件在目录中的所有磁带*文件上执行此操作?您可以尝试以下操作:
@echo关闭
对于(“.\tape*.txt”)中的%%F,请执行以下操作(
对于('findstr/N/X/C:'Header”“%%~F”“)中的/F“delims=:”%%N,请执行以下操作(
调用:子“%%~F”%%N
)
)
退出/B
:SUB
设置/A“跳过=%~2+3”
对于/F“skip=%skip%usebackq delims=“%%L in(“%1”)do(
回波(%%L%~n1)
)
退出/B
以下是另一种方法:
@echo关闭
对于(“.\tape*.txt”)中的%%F,请执行以下操作(
对于/F%%C in(“^<“%%~F”find/C/V“”),请执行以下操作(
设置/A“POS=0”&设置“NAME=%%~nF”
<“%%~F”(
setlocal EnableDelayedExpansion
对于(1,1,%%C)中的/L%%I,请执行以下操作(
设置“行=“&set/P行=“”
如果“!LINE!”==“Header”(
设置/A“位置=%%I+3”
)
如果%%I GTR!POS!GTR 0如果%%I GTR!POS(
echo(!LINE!!名称!
)
)
端部
)
)
)
@echo off
setlocal EnableDelayedExpansion
对于/F“tokens=1,2 delims=:”%%a in('findstr/N“Header”tape*)do(
(对于在(-2,1,%%b)中的/L%%i,执行设置/P“=”
对于(1,1,4)中的/L%%i,请设置/P“line=“&echo!line!%%a
)<“%%a”
)
到目前为止你都试了些什么,你被卡在哪里了?真的很好。不应该按一下要确保文件引用始终是相对的,并且在findstr
输出中没有任何额外的冒号?@MCND:好的,是的。必要的是tape*
通配符以前没有任何驱动器或路径。尝试了这个方法,但它只输出文件的最后一行和文件名。这似乎工作得很好!非常感谢。这将为我节省大量时间。从技术上讲,这并不是我想要的,但它解决了我的问题。谢谢。这个“解决方案”不是基于规范。“Header”
字符串和下面的4行在哪里?
@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
@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"
)