2

我有一个巨大的文本文件,它的每一行都包含一个带有模式 FEATURE_ 的字符串。我想从这个 txt 文件中读取每一行,并从文件中删除包含相同 FEATURE_字符串的所有其他行。

请建议 DOS 和 perl cmd 执行此操作

例如

输入:

#ifdef FEATURE_ABCD
#ifdef FEATURE_GHDI
#ifdef FEATURE_ABCD
#ifdef FEATURE_WXYZ
#ifdef FEATURE_ABCD
#ifdef FEATURE_WXYZ
#ifdef FEATURE_GHDI
#ifdef FEATUREGHDI
#define FEATURE_ABCD
#define FEATUREGHDI
/* FEATURE_GHDI */

输出:

#ifdef FEATURE_ABCD
#ifdef FEATURE_GHDI
#ifdef FEATURE_WXYZ
#ifdef FEATUREGHDI
4

4 回答 4

2

假设您的文本文件是FEATURE.TXT,试试这个:

@ECHO OFF & setlocal enabledelayedexpansion
for /f "delims=" %%i in (FEATURE.TXT) do (
    set "line0=%%i"
    set "line=!line0:*FEATURE=!"
    if not "!line0!"=="!line!" (
        for /f %%j in ("!line!") do set "line=%%j"
        if not defined $a!line! (
            set "$a!line!=!line!"
            (echo(!line0!)
        )
    )
)   

如果>>OUTPUT.TXT(echo(!line0!)命令之后放置,则可以将输出重定向到文件。

输出是:

#ifdef FEATURE_ABCD
#ifdef FEATURE_GHDI
#ifdef FEATURE_WXYZ
#ifdef FEATUREGHDI

编辑:加快代码速度的一些改进。

于 2013-04-20T19:56:45.637 回答
1
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /f "delims==" %%i IN ('set found 2^>nul') DO SET "%%i="
SET found=FEATURE_
SET /a count=0
(
FOR /f "delims=" %%i IN ('findstr /n "$" ^<feature.txt') DO (
 SET feature=%%i
 SET line=!feature:*:=!
 IF DEFINED line (
  SET feature=!line:*FEATURE_=!
  IF "!line!"=="!feature!" (ECHO(!line!) ELSE (
   FOR /f %%f IN ("!feature!") DO SET feature=%%f&SET found|FINDSTR /e "=%%f" >NUL
   IF ERRORLEVEL 1 (
    ECHO(!line!
    SET found!count!=!feature!
    SET /a count+=1
   ) 
  )
 ) ELSE (ECHO()
)
) >newfile.txt

对于每一行,包括空行,

  • 给行编号,然后去掉数字 如果原始为空,则生成一个空行
  • 否则,查看该行是否包含目标文本,如果没有则回显
  • 否则,查看target后面的字符串是否已经找到。
  • 如果没有,则生成该行并将新的目标后缀记录在foundcounter

除了 Aacin 的评论,也许你应该坐下来喝杯热茶,想想你在这里真正想要什么。

如果你按照你说的做,那么序列

#ifdef FEATURE_ABCD
something
endif

或者

#ifdef FEATURE_ABCD something

可能会产生你并不真正想要的东西——以及怎么样

#ifdef FEATURE_ABCD
...
#define FEATURE_ABCD
...
#ifdef FEATURE_ABCD

??

于 2013-04-21T06:16:39.853 回答
0

最小的代码和功能:

@echo OFF

Set "File=Input.txt"
Set "OutputFile=Output.txt"

For /F "Usebackq Tokens=2,* delims= " %%# in ("%File%") Do (
    Echo "%%#" | Find /I "Feature_" 1>NUL && (
        (Type "Features.txt" | FIND /I "%%#" 1>NUL) || (Echo %%#>>"%OutputFile%")))

代码省略没有“Feature_”字符串的行如果找到有效字符串,则在输出文件中查找该字符串是否已存在以添加或省略该字符串。

用您的输入文本进行测试,收到正确的输出:

#ifdef FEATURE_ABCD
#ifdef FEATURE_GHDI
#ifdef FEATURE_WXYZ
于 2013-04-21T08:36:30.137 回答
0

有几种不同的方法可以解决这个问题,每种方法都有自己的特点。最快的解决方案在输入文件的每一行中执行最少数量的命令,特别是避免使用外部命令。下面的批处理文件旨在快速处理具有许多匹配行的巨大文本文件。该方法首先创建一个带有要删除的行数的辅助文件(使用 FINDSTR 命令),然后将此文件与原始文件进行文件合并处理。

@echo off
setlocal EnableDelayedExpansion

set string=FEATURE_

rem Run FINDSTR to find the lines with the target string and store the numbers of the lines that will be deleted
(for /F "tokens=1* delims=:" %%a in ('findstr /N "%string%" inputFile.txt') do (
   set "line=%%b"
   for /F %%c in ("!line:*%string%=!") do (
      rem If this is the first line with the target string
      if not defined string[%%c] (
         rem Define the target string (and preserve this line)
         set string[%%c]=0
      ) else (
         rem Mark this line for deletion
         echo %%a
      )
   )
)) > linesToDelete.txt
rem Insert the EndOfFile mark
echo 0 >> linesToDelete.txt

rem Merge numbers of lines to delete (from STDIN) and input file (from FOR command)
< linesToDelete.txt (
   set /P lineToDelete=
   for /F "tokens=1* delims=:" %%a in ('findstr /N "^" inputFile.txt') do (
      if %%a neq !lineToDelete! (
         rem Preserve this line
         echo(%%b
      ) else (
         rem Ignore this line and pass to next one to delete
         set /P lineToDelete=
      )
   )
) > outputFile.txt

del linesToDelete.txt

如果输入文件包含特殊的 Batch 字符,例如! < | > &. 如果需要,此限制可能是固定的。

于 2013-04-21T17:07:45.573 回答