如何在大型文本文档中查找和删除具有下一行或上一行的特定行
How find and remove specific line with next or previous lines in large text document
我想知道如何从包含 500 000 行的大型文本文档中删除特定字符串。按内容查找行,但同时获取文本文档顺序中的当前行索引值,不得打扰,以删除找到的行的下一行或上一行,换句话说,按索引查找最近的行,以删除大文档中的两者.因为我尝试使用 File.WriteAllLines
程序的任何方法都会以这样的大小挂起。我已主动请求此文件,似乎需要找到其他方式。例如文件内容为:
1. line 1
2. line 2
3. line 3
4. line 4
5. line 5
要查找和删除的行是:
string input = "line 3"
通过删除找到的行索引和下一行的下一行索引 + 1 来得到这个结果,如果找到的行索引号是奇数:
line 1
line 2
line 5
同时能够删除找到的行索引和索引 - 1 前一行,如果找到的行索引为偶数用于搜索字符串:
string input = "line 4"
结果应该是:
line 1
line 2
line 5
并知道文本文档中是否不存在该行。
写入同一个文件。
让输入文件为 inputFile.txt
然后您可以使用 File.ReadAllLines()
方法获取该特定文件中的所有行。然后使用 IndexOf()
方法在该列表中查找特定行的索引,如果找不到意味着它将 return -1
然后使用 RemoveAt()
删除该行具体指标。考虑代码:
List<string> linesInFile = File.ReadAllLines(filePath).ToList(); // gives you list of lines
string input = "line 3";
int lineIndex = linesInFile.IndexOf(input);
if (lineIndex != -1)
{
linesInFile.RemoveAt(lineIndex);
}
// If you may have more number of match for particular line means you can try this as well :
linesInFile.RemoveAll(x=> x== input);
如果你想把它写回文件意味着使用这一行:
File.WriteAllLines(filePath,linesInFile);
如果你想处理非常大的文件,你应该使用FileStream
以避免将所有内容加载到内存中。
为了满足你的最后一个要求,你可以一行一行地读。它实际上使您的代码更简单。
var inputFileName = @"D:\test-input.txt";
var outputFileName = Path.GetTempFileName();
var search = "line 4";
using (var strInp = File.Open(inputFileName, FileMode.Open))
using (var strOtp = File.Open(outputFileName, FileMode.Create))
using (var reader = new StreamReader(strInp))
using (var writer = new StreamWriter(strOtp))
{
while (reader.Peek() >= 0)
{
var lineOdd = reader.ReadLine();
var lineEven = (string)null;
if (reader.Peek() >= 0)
lineEven = reader.ReadLine();
if(lineOdd != search && lineEven != search)
{
writer.WriteLine(lineOdd);
if(lineEven != null)
writer.WriteLine(lineEven);
}
}
}
// at this point, operation is sucessfull
// rename temp file with original one
File.Delete(inputFileName);
File.Move(outputFileName, inputFileName);
private static void RemoveLines(string lineToRemove, bool skipPrevious, bool skipNext)
{
string previousLine = string.Empty;
string currentLine;
bool isNext = false;
using (StreamWriter sw = File.CreateText(@"output.txt"))
{
using (StreamReader sr = File.OpenText(@"input.txt"))
{
while ((currentLine = sr.ReadLine()) != null)
{
if (isNext)
{
currentLine = string.Empty;
isNext = false;
}
if (currentLine == lineToRemove)
{
if (skipPrevious)
{
previousLine = string.Empty;
}
if (skipNext)
{
currentLine = string.Empty;
isNext = true;
}
}
if (previousLine != string.Empty && previousLine != lineToRemove)
{
sw.WriteLine(previousLine);
}
previousLine = currentLine;
}
}
if (previousLine != string.Empty && previousLine != lineToRemove)
{
sw.WriteLine(previousLine);
}
}
}
还没有测试过,但这会给出所需的指示。
我想知道如何从包含 500 000 行的大型文本文档中删除特定字符串。按内容查找行,但同时获取文本文档顺序中的当前行索引值,不得打扰,以删除找到的行的下一行或上一行,换句话说,按索引查找最近的行,以删除大文档中的两者.因为我尝试使用 File.WriteAllLines
程序的任何方法都会以这样的大小挂起。我已主动请求此文件,似乎需要找到其他方式。例如文件内容为:
1. line 1
2. line 2
3. line 3
4. line 4
5. line 5
要查找和删除的行是:
string input = "line 3"
通过删除找到的行索引和下一行的下一行索引 + 1 来得到这个结果,如果找到的行索引号是奇数:
line 1
line 2
line 5
同时能够删除找到的行索引和索引 - 1 前一行,如果找到的行索引为偶数用于搜索字符串:
string input = "line 4"
结果应该是:
line 1
line 2
line 5
并知道文本文档中是否不存在该行。
写入同一个文件。
让输入文件为 inputFile.txt
然后您可以使用 File.ReadAllLines()
方法获取该特定文件中的所有行。然后使用 IndexOf()
方法在该列表中查找特定行的索引,如果找不到意味着它将 return -1
然后使用 RemoveAt()
删除该行具体指标。考虑代码:
List<string> linesInFile = File.ReadAllLines(filePath).ToList(); // gives you list of lines
string input = "line 3";
int lineIndex = linesInFile.IndexOf(input);
if (lineIndex != -1)
{
linesInFile.RemoveAt(lineIndex);
}
// If you may have more number of match for particular line means you can try this as well :
linesInFile.RemoveAll(x=> x== input);
如果你想把它写回文件意味着使用这一行:
File.WriteAllLines(filePath,linesInFile);
如果你想处理非常大的文件,你应该使用FileStream
以避免将所有内容加载到内存中。
为了满足你的最后一个要求,你可以一行一行地读。它实际上使您的代码更简单。
var inputFileName = @"D:\test-input.txt";
var outputFileName = Path.GetTempFileName();
var search = "line 4";
using (var strInp = File.Open(inputFileName, FileMode.Open))
using (var strOtp = File.Open(outputFileName, FileMode.Create))
using (var reader = new StreamReader(strInp))
using (var writer = new StreamWriter(strOtp))
{
while (reader.Peek() >= 0)
{
var lineOdd = reader.ReadLine();
var lineEven = (string)null;
if (reader.Peek() >= 0)
lineEven = reader.ReadLine();
if(lineOdd != search && lineEven != search)
{
writer.WriteLine(lineOdd);
if(lineEven != null)
writer.WriteLine(lineEven);
}
}
}
// at this point, operation is sucessfull
// rename temp file with original one
File.Delete(inputFileName);
File.Move(outputFileName, inputFileName);
private static void RemoveLines(string lineToRemove, bool skipPrevious, bool skipNext)
{
string previousLine = string.Empty;
string currentLine;
bool isNext = false;
using (StreamWriter sw = File.CreateText(@"output.txt"))
{
using (StreamReader sr = File.OpenText(@"input.txt"))
{
while ((currentLine = sr.ReadLine()) != null)
{
if (isNext)
{
currentLine = string.Empty;
isNext = false;
}
if (currentLine == lineToRemove)
{
if (skipPrevious)
{
previousLine = string.Empty;
}
if (skipNext)
{
currentLine = string.Empty;
isNext = true;
}
}
if (previousLine != string.Empty && previousLine != lineToRemove)
{
sw.WriteLine(previousLine);
}
previousLine = currentLine;
}
}
if (previousLine != string.Empty && previousLine != lineToRemove)
{
sw.WriteLine(previousLine);
}
}
}
还没有测试过,但这会给出所需的指示。