-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
142 lines (117 loc) · 5.32 KB
/
Program.cs
File metadata and controls
142 lines (117 loc) · 5.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
using System.CommandLine;
using System.Text.RegularExpressions;
namespace HugeFileInspector
{
class Program
{
static async Task<int> Main(string[] args)
{
var rootCommand = new RootCommand("HugeFileInspector - Search and replace text patterns in large files.");
var inputOption = new Option<FileInfo>(
aliases: ["--input", "-i"],
description: "The input file to process.")
{ IsRequired = true };
var outputOption = new Option<string>(
aliases: ["--output", "-o"],
description: "The output file to log results instead of the console. \r\n In replace mode, it is mandatory.");
var patternOption = new Option<string>(
aliases: ["--find", "-f"],
description: "The text pattern or regular expression to search for.")
{ IsRequired = true };
var replaceOption = new Option<string>(
aliases: ["--replace", "-r"],
description: "The replacement text (optional).");
var distinctOption = new Option<bool>(
aliases: ["--distinct", "-d"],
description: "Only logs distinct texts found in the file.");
rootCommand.AddOption(inputOption);
rootCommand.AddOption(outputOption);
rootCommand.AddOption(patternOption);
rootCommand.AddOption(replaceOption);
rootCommand.AddOption(distinctOption);
rootCommand.SetHandler(ProcessFileAsync, inputOption, outputOption, patternOption, replaceOption, distinctOption);
return await rootCommand.InvokeAsync(args);
}
static async Task ProcessFileAsync(FileInfo inputFile, string? outputFile, string pattern, string replaceText, bool distinctMode)
{
if (!inputFile.Exists)
{
Console.WriteLine($"Error: The file '{inputFile.FullName}' does not exist.");
return;
}
bool outputFileProvided = !string.IsNullOrEmpty(outputFile);
bool isReplacing = !string.IsNullOrEmpty(replaceText);
if (isReplacing && !outputFileProvided)
{
Console.WriteLine($"Error: The output file path is not provided. \r\nIt is optional in find mode but mandatory in replace mode");
return;
}
if (isReplacing && distinctMode)
{
Console.WriteLine($"Error: --replace and --distinct options can not be used at the same time");
return;
}
long totalMatches = 0;
long totalDistinctMatches = 0;
var distinctMatches = new List<string>();
try
{
using var reader = new StreamReader(inputFile.FullName);
StreamWriter? writer = null;
if (outputFileProvided)
{
writer = new StreamWriter(outputFile!);
}
string? line;
int lineNumber = 0;
var regex = new Regex(pattern, RegexOptions.Compiled);
while ((line = await reader.ReadLineAsync()) != null)
{
lineNumber++;
var matches = regex.Matches(line);
var matchFound = matches.Count > 0;
var distinctModeAndNewMatchFound = distinctMode && !distinctMatches.Contains(line);
if (matchFound)
{
totalMatches += matches.Count;
if (!distinctMode || distinctModeAndNewMatchFound)
{
Console.WriteLine($"Line {lineNumber}:\t {line}");
if (distinctModeAndNewMatchFound)
{
distinctMatches.Add(line);
totalDistinctMatches += matches.Count;
}
}
}
if (matchFound && !isReplacing && outputFileProvided && (!distinctMode || distinctModeAndNewMatchFound))
{
await writer!.WriteLineAsync($"Line {lineNumber}:\t {line}");
}
if (isReplacing)
{
if (matchFound)
{
line = regex.Replace(line, replaceText);
}
await writer!.WriteLineAsync(line);
}
}
Console.WriteLine($"\nTotal matches: {totalMatches}");
if (distinctMode)
{
Console.WriteLine($"Total distinct matches: {totalDistinctMatches}");
}
if (outputFileProvided && writer != null)
{
await writer!.FlushAsync();
writer.Dispose();
}
}
catch (Exception ex)
{
Console.WriteLine($"Error processing the file: {ex.Message}");
}
}
}
}