我有一个大文本文件,数百万行。
我很想搜索一个[unique word],并在[unique word]之前复制30行,然后复制100行,然后将这些行输出到另一个文件。
最好命名为[唯一词] .txt
我找到了,但是没有搜索。
DOS Batch To Copy First 100 Lines Of A Text File<<<
@ECHO OFF
setlocal enabledelayedexpansion
SET /P maxlines=Enter number of lines to be moved to new txt document:
SET /A linecount=0
FOR /F "delims=" %%A IN (textfile1.txt) DO (
IF !linecount! GEQ %maxlines% GOTO ExitLoop
ECHO %%A >> C:\users\username\desktop\textfile2.txt
SET /A linecount+=1
)
:ExitLoop
ECHO All Done.
ECHO.
ECHO Press any key to close this window.
PAUSE>NUL
EXIT
举一个我想要的例子
要放置在new_file.txt中的唯一单词之前的2行和唯一单词之后的3行
sorce_file.txt具有此内容
world 1
world 2
world 3
world 4
world 5
unique word
world 6
world 7
world 8
world 9
world 10
我运行脚本,并且输出new_file.txt具有此
world 4
world 5
unique word
world 6
world 7
world 8
答案 0 :(得分:1)
使用JREPL.BAT - a regular expression command line text processing utility:
jrepl "UniqueWord" "" /L /K 30:100 /F "input.txt" /O "UniqueWord.txt"
或者忽略在较大单词中嵌入了UniqueWord的单词:
jrepl "\bUniqueWord\b" "" /K 30:100 /F "input.txt" /O "UniqueWord.txt"
使用jrepl /?help
获取脚本中所有可用文档的列表。
JREPL是纯脚本(混合JScript /批处理),可以从XP开始在任何Windows计算机上本机运行,而无需第三方exe。
JREPL比任何“纯”本地批处理解决方案都快得多。但是,它的速度不及grep这样的编译可执行文件。
答案 1 :(得分:1)
使用Select-String
cmdlet及其-Context
参数的PowerShell单一衬里,
分批包装:
powershell -NoP -C "Select-String -Path .\Source_File.txt -Pattern 'unique word' -Context 30,100|ForEach-Object{$_.Context.PreContext;$_.Line;$_.Context.PostContext}|Set-Content New_File.txt"
应该比纯批处理更快。
使用-Context 2,3
的输出示例
> Get-Content .\New_File.txt
world 4
world 5
unique word
world 6
world 7
world 8
答案 2 :(得分:0)
这样的变化呢? 回声%% A |找到“ yourWord” >> outputFile.txt
除非您想要使用Cygwin或PowerShell进行更复杂的搜索? 但是使用批处理脚本迭代文件行可能会非常慢,也许由CSC编译的短C#代码会更好。 让我知道你是否想要。
我的测试批次现在看起来像这样,但是除非您在处理计数在源行而不是在结果上起作用之前进行过滤(有些可能为空)。
@ECHO OFF
setlocal enabledelayedexpansion
del textfile2.txt
SET /A maxlines=10
SET /P maxlines=Enter number of lines to be moved to new txt document:
SET /A linecount=0
FOR /F "delims=" %%A IN (x.txt) DO (
IF !linecount! GEQ %maxlines% GOTO ExitLoop
SET /A linecount+=1
ECHO %%A | find ";" >> textfile2.txt
)
:ExitLoop
ECHO All Done.
例如,C#版本可能看起来像(假设与批处理脚本相比更具可读性):
using System;
using System.Collections.Generic;
using System.IO;
namespace BatchTest
{
class Program
{
public static void Main(string[] args)
{
String inFile = args[0], outFile = args[1], word = args[2], line;
int nextLines = 100;
Queue<String> qt = new Queue<String>();
using (StreamReader sr = new StreamReader(inFile))
using (StreamWriter sw = new StreamWriter(outFile))
while ((line = sr.ReadLine()) != null)
{
qt.Enqueue(line);
if (line.Contains(word))
{
foreach (var el in qt)
{
sw.WriteLine(el);
}
qt.Clear();
int i = nextLines;
while ((i-- > 0) && (line = sr.ReadLine()) != null)
{
if (line.Contains(word)) i = nextLines;
sw.WriteLine(line);
}
} else if (qt.Count > 29) qt.Dequeue();
}
}
}
}
并编译在eltomjan\ETEhomeTools\CSharp\Compile.bat上在我的GitHub上发布的此类批处理文件,该搜索的灵感可能在以下某个地方找到
:setlocal enabledelayedexpansion enableextensions
set LIBS=
for %%x in (*.dll) do (
echo %%x|findstr ",">nul 2>&1
if errorlevel 1 (set LIBS=!LIBS!,%%x) else (set LIBS=!LIBS!,"%%x")
)
if "%LIBS%"=="" (for /F %%v in ('dir /s %WINDIR%\Microsoft.NET\csc.exe /B') do echo %%v -debug %%* > cscLatest.bat ) else (for /F %%v in ('dir /s %WINDIR%\Microsoft.NET\csc.exe /B') do echo %%v -debug /r:%LIBS:~1% %%* > cscLatest.bat )
if "%1" == "" cscLatest.bat *.cs
cscLatest.bat %*
如果您不想在Windows文件夹中搜索某些CSC版本。
答案 3 :(得分:0)
查找唯一单词的行号,进行一些算术运算以计算起始行和结束行。然后输出之间的线。以下代码甚至保留空行:
@echo off
setlocal
set "file=yourfile.txt"
for /f "tokens=1 delims=[]" %%a in ('find /n "[unique word]" "%file%"') do set line=%%a
set /a startline=line-30
set /a endline=line+100
if %startline% lss 1 (set "skip=") else (set "skip=skip=%startline%")
set /a count=startline
for /f "%skip% tokens=1,* delims=:" %%a in ('findstr /n "^" "%file%"') do (
if !count! geq %endline% goto :done
echo(%%b
set /a count+=1
)
:done
别指望它很快...在我的系统上,包含11500行的文件大约需要10秒