Windows批处理,分隔符分割文件,细化

时间:2015-07-31 15:11:19

标签: windows batch-file

我有一个文件夹,里面有我需要根据分隔符(可选)分割的文本文件。我找到了如何在此处实际拆分文件的答案:Split text file into 2 files by separator

@echo off&setlocal
set "file=_frmCore.frm"
for /f "delims=[]" %%i in ('^<"%file%" find /n "SearchTermHere"') do set "split=%%i"
(for /f "tokens=1*delims=[]" %%i in ('^<"%file%" find /n /v ""') do if %%i lss %split% echo(%%j)>"%file%.new1"
<"%file%">"%file%.new2" more +%split%
type "%file%.new?"

非常适合它,但我需要一些改进,不知道从哪里开始。寻找:

  1. 将其包装在目录中所有文件的循环中(无需担心子文件夹)
  2. “SearchTermHere”是第一行(唯一一行),前一行有一个特定术语,我宁愿为安全而匹配......我怎么能告诉它“PreviousLine / r / nSearchTermHere / R / N“?这里不确定正确的语法。
  3. 不是创建两个新文件,而是将“搜索词后”部分移动到新文件并将其从原始文件中删除
  4. 参数化要操作的文件夹名称,以便我可以从其他程序调用
  5. (道歉......我已经尝试破译这些代码并找出了什么做了什么,并试图从那里开始,但这些东西不是我的一杯茶,并且在正确的方向上的强力推动将是美好的)< / p>

3 个答案:

答案 0 :(得分:1)

@ECHO OFF >NUL
SETLOCAL enableextensions
rem enabledelayedexpansion
set "_files=*.frm"
set "_sfind=SearchTermHere"
if not "%~1"=="" if exist "%~1\" (
  pushd "%~1"
  set "_popd=popd"
) else ( set "_popd=" )
for /F "delims=" %%G in ('findstr /m "^%_sfind%$" %_files%') do (
  type NUL > "%%G.new1"
  type NUL > "%%G.new2"
  for /f "delims=:" %%i in ('findstr /n "^%_sfind%$" "%%G"') do (
    for /f "tokens=1* delims=:" %%I in ('findstr /n "^" "%%G"') do (
        if %%I lss %%i (
          >> "%%G.new1" echo(%%J
        )
        if %%I gtr %%i (
          >> "%%G.new2" echo(%%J
        )
    )
  )
  rem remove `ECHO` from next line no sooner than debugged!
  ECHO move /Y "%%G.new1" "%%G" 
  type "%%G.new?"
)
%_popd%

Changes made in your code:

  1. Wrap it in a loop for all files in the directory: see for /F "delims=" %%G loop against all files matching your criteria: findstr /m "^%_sfind%$" %_files%.
  2. "SearchTermHere" is the first on a line (the only on a line): ^=beginning of line and $=end of line in findstr /m "^%_sfind%$" %_files%; used findstr command rather than find.
  3. Rather than creating two new files, move the "after search term" portion to a new file and remove it from the original: see the move /Y "%%G.new1" "%%G" workaround. Operational move command is ECHOed here merely for debugging purposes. Remove ECHO from that line no sooner than debugged!
  4. Parameterize folder name to operate in so I can call from other programs:
    • call "batch path\31749577.bat" "folder path"
    • see %~1 test: if a parameter is supplied to the batch and represents a folder, (more in Command Line arguments (Parameters)) and
    • see pushd - popd pair: PUSHD changes the current directory/folder and store the previous folder/path for use by the POPD command.

The tricky <"%%G">"%%G.new2" more +%%i command substituted with less effective but clear to understand if %%I gtr %%i ( ... inside the %%I loop. However, next code snippet (entire %%G loop) will work as well:

for /F "delims=" %%G in ('findstr /m "^%_sfind%$" %_files%') do (
  for /f "delims=:" %%i in ('findstr /n "^%_sfind%$" "%%G"') do (
    >"%%G.new1" (for /f "tokens=1* delims=:" %%I in ('
         findstr /n "^" "%%G"') do if %%I lss %%i echo(%%J)
    <"%%G">"%%G.new2" more +%%i
  )
  rem remove `ECHO` from next line no sooner than debugged!
  ECHO move /Y "%%G.new1" "%%G" 
  type "%%G.new?"
)

答案 1 :(得分:1)

对不起。虽然您的描述很广泛,但也令人困惑。下面的批处理文件:

  • 搜索“SearchTermHere”行。
  • 如果前一行是“PreviousLine”:   从SearchTerm之后的行移到文件结尾到另一个文件
  • 对文件夹中的所有文件重复上一个过程。

@echo off
setlocal EnableDelayedExpansion

set "find=SearchTermHere"
set "prevLine=PreviousLine"

rem Process the folder given in parameter
cd %1

rem Process all files in folder
for /F "delims=" %%F in ('dir /A-D /B') do (

   rem Get the line number of the search line - 1
   set "numLines="
   for /F "delims=:" %%a in ('findstr /N "^%find%$" "%%F"') do set /A "numLines=%%a-1"
   if defined numLines (

      rem Open a code block to read-input-file/create-output-file
      < "%%F" (

         rem Copy numLines-1 lines
         for /L %%i in (1,1,%numLines%) do (
            set "line="
            set /P "line="
            echo(!line!
         )

         rem If the line before search is prevLine
         if "!line!" equ "%prevLine%" (
            rem Copy just the search line to original file
            set /P "line="
            echo !line!
            rem and copy the rest of lines to another file
            findstr "^" > "%%~nF-PART2%%~xF"
         )

      ) > "%%F.tmp"

      if exist "%%~nF-PART2%%~xF" (
         rem Replace original file with created output file (first part)
         move /Y "%%F.tmp" "%%F" > NUL
      ) else (
         rem Remove the output file
         del "%%F.tmp"
      )

   )

)

有关此方法的进一步说明,请参阅this post

答案 2 :(得分:0)

抱歉,我无法使用任何一种建议的解决方案。然而,他们确实提供了帮助 - 我花了两天时间了解批处理文件中涉及的(奇数)语法和操作,并提出了以下建议。它没有做我想要的所有事情(我改变了输出文件的程序以获得进一步的支持),但它确实完成了工作:

@ECHO off
setlocal EnableDelayedExpansion

:: change the working directory to match the input
cd /D %~d1
cd %~p1\

:: loop all .frm files and find the CodeBehindForm string
for %%F in (*.frm) do (

 for /F "delims=[]" %%a in ('^<%%F find /n "CodeBehindForm"') do (
    if %%a gtr 0 ( 
        for /F "tokens=1*delims=[]" %%i in ('^<"%%F" find /n /v ""') do if %%i gtr %%a echo(%%j)>>"%%~nF.vb" 
        for /F "tokens=1*delims=[]" %%i in ('^<"%%F" find /n /v ""') do if %%i lss %%a echo(%%j)>>"%%~nF.fwm" 

        :: if the codebehind was found and parsed out, there's a .fwm and .vb file
        :: remove the original
        if exist %%~nF.vb del %%F
    )
)
:: change the .fwm extensions back to their original .frm extensions
ren *.fwm *.frm

我确信它在很多方面都不“正确”,但现在它已经完成了工作。

感谢您的帮助。

相关问题