Example #1
0
        private static void BuildSearchResultsFileContent(ConsoleCommand consoleCommand, GrepResultCollection grepResultCollection, List <Match> matches, string filename, long fileSize, string fileRaw)
        {
            bool IgnoreBreaksFlag = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.IgnoreBreaks);
            bool IgnoreCaseFlag   = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.IgnoreCase);
            bool ContextFlag      = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.Context);
            bool NResultsFlag     = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.NResults);

            // Build file context search pattern
            string SearchTerm    = consoleCommand.CommandArgs[ConsoleFlag.SearchTerm];
            int    ContextLength = ContextFlag ? Convert.ToInt32(consoleCommand.CommandArgs[ConsoleFlag.Context]) : 0;

            matches.ToList().ForEach(match =>
            {
                string LeadingContext  = string.Empty;
                string TrailingContext = string.Empty;

                if (ContextFlag)
                {
                    // Rebuild matches with contextual text
                    int LeadingContextStartIndex = match.Groups["MatchedString"].Index - ContextLength < 0 ? 0 : match.Groups["MatchedString"].Index - ContextLength;
                    int LeadingContextLength     = match.Groups["MatchedString"].Index < ContextLength ? match.Groups["MatchedString"].Index : ContextLength;

                    int TrailingContextStartIndex = match.Groups["MatchedString"].Index + match.Groups["MatchedString"].Value.Length;
                    int TrailingContextLength     = TrailingContextStartIndex + ContextLength > fileRaw.Length ? fileRaw.Length - TrailingContextStartIndex : ContextLength;

                    LeadingContext  = Environment.NewLine + fileRaw.Substring(LeadingContextStartIndex, LeadingContextLength);
                    TrailingContext = fileRaw.Substring(TrailingContextStartIndex, TrailingContextLength) + Environment.NewLine;
                }

                string MatchedString = match.Groups["MatchedString"].Value;

                GrepResult GrepResult = new GrepResult(filename, ResultScope.FileContent)
                {
                    FileSize              = fileSize,
                    LeadingContextString  = LeadingContext,
                    TrailingContextString = TrailingContext,
                    MatchedString         = MatchedString
                };

                // Line number
                int LineNumber        = fileRaw.Substring(0, match.Groups["MatchedString"].Index).Split('\n').Length;
                GrepResult.LineNumber = LineNumber;

                lock (grepResultCollection)
                {
                    if (!NResultsFlag || grepResultCollection.Count < Convert.ToInt32(consoleCommand.CommandArgs[ConsoleFlag.NResults]))
                    {
                        grepResultCollection.AddItem(GrepResult);
                    }
                }
            });
        }
Example #2
0
        private static void BuildSearchResultsFileContent(ConsoleCommand consoleCommand, GrepResultCollection grepResultCollection, List <Match> matches, string filename, string fileRaw, string searchPattern)
        {
            bool IgnoreBreaksFlag = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.IgnoreBreaks);
            bool IgnoreCaseFlag   = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.IgnoreCase);
            bool ContextFlag      = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.Context);

            // Build file context search pattern
            string SearchTerm     = consoleCommand.CommandArgs[ConsoleFlag.SearchTerm];
            int    ContextLength  = ContextFlag ? Convert.ToInt32(consoleCommand.CommandArgs[ConsoleFlag.Context]) : 0;
            string ContextPattern = @"(?:(?<ContextString>.{0," + ContextLength.ToString() + @"}?))";
            Regex  ContextRegex   = new Regex(ContextPattern + searchPattern);

            matches.ToList().ForEach(match =>
            {
                // Rebuild matches with contextual text
                if (ContextFlag)
                {
                    int ContextStartIndex = (match.Index - ContextLength) < 0 ? 0 : (match.Index - ContextLength);
                    match = ContextRegex.Match(fileRaw, ContextStartIndex);
                }

                string ContextString = ContextFlag ? match.Groups["ContextString"]?.Value ?? string.Empty : string.Empty;
                string MatchedString = match.Groups["MatchedString"].Value;

                GrepResult GrepResult = new GrepResult(filename, ResultScope.FileContent)
                {
                    LeadingContextString = ContextString,
                    MatchedString        = MatchedString
                };

                // Line number
                if (!IgnoreBreaksFlag)
                {
                    int LineNumber        = fileRaw.Substring(0, match.Groups["MatchedString"].Index).Split('\n').Length;
                    GrepResult.LineNumber = LineNumber;
                }

                grepResultCollection.AddItem(GrepResult);
            });
        }
Example #3
0
        private static void ProcessCommand(GrepResultCollection grepResultCollection, IEnumerable <string> files, ConsoleCommand consoleCommand, RegexOptions optionsFlags)
        {
            bool FixedStringsFlag    = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.FixedStrings);
            bool DeleteFlag          = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.Delete);
            bool ReplaceFlag         = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.Replace);
            bool WriteFlag           = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.Write);
            bool FileNamesOnlyFlag   = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.FileNamesOnly);
            bool FileSizeMinimumFlag = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.FileSizeMinimum);
            bool FileSizeMaximumFlag = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.FileSizeMaximum);
            bool NResultsFlag        = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.NResults);

            int FileReadFailedCount    = 0;
            int FileWriteFailedCount   = 0;
            int DeleteSuccessCount     = 0;
            int ReplacedSuccessCount   = 0;
            int TotalFilesMatchedCount = 0;

            long FileSizeMin = GetFileSizeMinimum(consoleCommand);
            long FileSizeMax = GetFileSizeMaximum(consoleCommand);

            // Build content search pattern
            string SearchPattern = BuildSearchPattern(consoleCommand);
            Regex  SearchRegex   = new Regex(SearchPattern, optionsFlags);

            if (FileNamesOnlyFlag)
            {
                Regex FileNameRegex = new Regex(@"^(.+)[\/\\](?<FileName>[^\/\\]+)$");
                var   Matches       = new List <GrepResult>();

                files.ToList().ForEach(file =>
                {
                    if (!NResultsFlag || Matches.Count < Convert.ToInt32(consoleCommand.CommandArgs[ConsoleFlag.NResults]))
                    {
                        // Don't want to waste any time on files that have already been added
                        bool FileAdded = Matches.Any(x => x.SourceFile == file);
                        if (!FileAdded)
                        {
                            // Parse filename from path
                            var FileNameMatch = FileNameRegex.Match(file)?.Groups["FileName"];
                            if (FileNameMatch != null)
                            {
                                // Query against filename
                                var SearchMatch = SearchRegex.Match(FileNameMatch.Value);
                                if (SearchMatch != Match.Empty)
                                {
                                    // Write operations
                                    bool isWriteOperation = ReplaceFlag || DeleteFlag;
                                    if (isWriteOperation)
                                    {
                                        ProcessWriteOperations(consoleCommand, file, SearchPattern, Matches.Count, ref file, ref TotalFilesMatchedCount, ref DeleteSuccessCount, ref ReplacedSuccessCount, ref FileWriteFailedCount);
                                    }
                                    else
                                    {
                                        int TrailingContextStringStartIndex = FileNameMatch.Index + SearchMatch.Index + SearchMatch.Length;

                                        // Validate any filesize parameters
                                        var FileSize = FileSizeMaximumFlag || FileSizeMinimumFlag ? WindowsUtils.GetFileSizeOnDisk(file) : -1;
                                        bool FileSizevalidateSuccess = ValidateFileSize(consoleCommand, FileSize, FileSizeMin, FileSizeMax);

                                        if (FileSizevalidateSuccess)
                                        {
                                            GrepResult GrepResult = new GrepResult(file, ResultScope.FileName)
                                            {
                                                FileSize              = FileSize,
                                                LeadingContextString  = file.Substring(0, FileNameMatch.Index + SearchMatch.Index),
                                                MatchedString         = SearchMatch.Value,
                                                TrailingContextString = file.Substring(TrailingContextStringStartIndex, file.Length - TrailingContextStringStartIndex)
                                            };

                                            Matches.Add(GrepResult);
                                        }
                                    }
                                }
                            }
                        }
                    }
                });

                TotalFilesMatchedCount = Matches.Count();
                grepResultCollection.AddItemRange(Matches);
            }
            else
            {
                if (consoleCommand.CommandArgs[ConsoleFlag.SearchTerm] == string.Empty)
                {
                    throw new Exception("Error: Search term not supplied");
                }

                files.AsParallel().ForAll(file =>
                {
                    try
                    {
                        if (!NResultsFlag || grepResultCollection.Count < Convert.ToInt32(consoleCommand.CommandArgs[ConsoleFlag.NResults]))
                        {
                            List <Match> Matches = new List <Match>();

                            // Validate any filesize parameters
                            var FileSize = FileSizeMaximumFlag || FileSizeMinimumFlag ? WindowsUtils.GetFileSizeOnDisk(file) : -1;
                            bool FileSizevalidateSuccess = ValidateFileSize(consoleCommand, FileSize, FileSizeMin, FileSizeMax);

                            if (FileSizevalidateSuccess)
                            {
                                string FileRaw = File.ReadAllText(file);

                                Matches = SearchRegex.Matches(FileRaw).ToList();
                                if (Matches.Any())
                                {
                                    // Write operations
                                    bool isWriteOperation = ReplaceFlag || DeleteFlag;
                                    if (isWriteOperation)
                                    {
                                        ProcessWriteOperations(consoleCommand, file, SearchPattern, Matches.Count, ref FileRaw, ref TotalFilesMatchedCount, ref DeleteSuccessCount, ref ReplacedSuccessCount, ref FileWriteFailedCount);
                                    }

                                    // Read operations
                                    else
                                    {
                                        BuildSearchResultsFileContent(consoleCommand, grepResultCollection, Matches, file, FileSize, FileRaw);

                                        lock (_SearchLock)
                                        {
                                            TotalFilesMatchedCount++;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch
                    {
                        lock (_SearchLock)
                        {
                            FileReadFailedCount++;
                        }
                    }
                });
            }

            // Notify the user of any files that could not be read from or written to
            PublishFileAccessSummary(FileReadFailedCount, FileWriteFailedCount);

            // Publish command summary to console
            PublishCommandSummary(consoleCommand, grepResultCollection, TotalFilesMatchedCount, DeleteSuccessCount, ReplacedSuccessCount);
        }
Example #4
0
        private static void ProcessCommand(GrepResultCollection grepResultCollection, IEnumerable <string> files, ConsoleCommand consoleCommand, RegexOptions optionsFlags)
        {
            bool FixedStringsFlag  = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.FixedStrings);
            bool DeleteFlag        = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.Delete);
            bool ReplaceFlag       = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.Replace);
            bool WriteFlag         = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.Write);
            bool FileNamesOnlyFlag = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.FileNamesOnly);
            bool IgnoreBreaksFlag  = consoleCommand.CommandArgs.ContainsKey(ConsoleFlag.IgnoreBreaks);

            int FileReadFailedCount  = 0;
            int FileWriteFailedCount = 0;

            int DeleteSuccessCount   = 0;
            int ReplacedSuccessCount = 0;

            int FilesMatchedCount = 0;

            // Build content search pattern
            string SearchPattern = BuildSearchPattern(consoleCommand);
            Regex  SearchRegex   = new Regex(SearchPattern, optionsFlags);

            if (FileNamesOnlyFlag)
            {
                Regex FileNameRegex = new Regex(@"^(.+)[\/\\](?<FileName>[^\/\\]+)$");

                var Matches = new List <GrepResult>();
                files.ToList().ForEach(file =>
                {
                    // Don't want to waste any time on files that have already been added
                    bool FileAdded = Matches.Any(x => x.SourceFile == file);

                    if (!FileAdded)
                    {
                        // Parse filename from path
                        var FileNameMatch = FileNameRegex.Match(file)?.Groups["FileName"];
                        if (FileNameMatch != null)
                        {
                            // Query against filename
                            var SearchMatch = SearchRegex.Match(FileNameMatch.Value);
                            if (SearchMatch != Match.Empty)
                            {
                                var MatchedString = SearchMatch.Groups["MatchedString"];
                                int TrailingContextStringStartIndex = FileNameMatch.Index + FileNameMatch.Value.ToLower().IndexOf(MatchedString.Value.ToLower()) + MatchedString.Length;

                                GrepResult GrepResult = new GrepResult(file, ResultScope.FileName)
                                {
                                    LeadingContextString  = file.Substring(0, FileNameMatch.Index),
                                    MatchedString         = MatchedString.Value,
                                    TrailingContextString = file.Substring(TrailingContextStringStartIndex, file.Length - TrailingContextStringStartIndex)
                                };

                                Matches.Add(GrepResult);
                            }
                        }
                    }
                });

                FilesMatchedCount = Matches.Count();
                grepResultCollection.AddItemRange(Matches);
            }
            else
            {
                files.AsParallel().ForAll(file =>
                {
                    try
                    {
                        List <Match> Matches = new List <Match>();

                        string FileRaw = File.ReadAllText(file);

                        // Apply linebreak filtering options
                        if (IgnoreBreaksFlag)
                        {
                            string FileLineBreakFilteredNull  = FileRaw.Replace("\r", string.Empty).Replace("\n", string.Empty);
                            string FileLineBreakFilteredSpace = Regex.Replace(FileRaw, @"[\r\n]+", " ");

                            Matches.AddRange(SearchRegex.Matches(FileLineBreakFilteredNull));
                            Matches.AddRange(SearchRegex.Matches(FileLineBreakFilteredSpace));
                        }
                        else
                        {
                            Matches = SearchRegex.Matches(FileRaw).ToList();
                        }

                        if (Matches.Any())
                        {
                            // Write operations
                            bool isWriteOperation = ReplaceFlag || DeleteFlag;
                            if (isWriteOperation)
                            {
                                List <ConsoleItem> ConsoleItemCollection = new List <ConsoleItem>();

                                // FileName
                                ConsoleItemCollection.Add(new ConsoleItem()
                                {
                                    ForegroundColor = ConsoleColor.DarkYellow, Value = $"{file} "
                                });

                                try
                                {
                                    if (DeleteFlag)
                                    {
                                        // Delete file
                                        File.Delete(file);

                                        ConsoleItemCollection.Add(new ConsoleItem()
                                        {
                                            ForegroundColor = ConsoleColor.Red, Value = $"Deleted"
                                        });

                                        lock (_searchLock)
                                        {
                                            DeleteSuccessCount++;
                                        }
                                    }
                                    else if (ReplaceFlag)
                                    {
                                        // Replace all occurrences in file
                                        FileRaw = Regex.Replace(FileRaw, SearchPattern, consoleCommand.CommandArgs[ConsoleFlag.Replace]);
                                        File.WriteAllText(file, FileRaw);

                                        string MatchesText = Matches.Count == 1 ? "match" : "matches";
                                        ConsoleItemCollection.Add(new ConsoleItem()
                                        {
                                            ForegroundColor = ConsoleColor.DarkMagenta, Value = $"{Matches.Count} {MatchesText}"
                                        });

                                        lock (_searchLock)
                                        {
                                            ReplacedSuccessCount += Matches.Count;
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    ConsoleItemCollection.Add(new ConsoleItem()
                                    {
                                        ForegroundColor = ConsoleColor.Gray, BackgroundColor = ConsoleColor.DarkRed, Value = $"Access Denied"
                                    });

                                    lock (_searchLock)
                                    {
                                        FileWriteFailedCount++;
                                    }
                                }
                                finally
                                {
                                    // Empty buffer
                                    ConsoleItemCollection.Add(new ConsoleItem()
                                    {
                                        Value = Environment.NewLine
                                    });

                                    ConsoleUtils.WriteConsoleItemCollection(ConsoleItemCollection);

                                    lock (_searchLock)
                                    {
                                        FilesMatchedCount++;
                                    }
                                }
                            }

                            // Read operations
                            else
                            {
                                BuildSearchResultsFileContent(consoleCommand, grepResultCollection, Matches, file, FileRaw, SearchPattern);

                                lock (_searchLock)
                                {
                                    FilesMatchedCount++;
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        lock (_searchLock)
                        {
                            FileReadFailedCount++;
                        }
                    }
                });
            }

            // Notify the user of any files that could not be read from or written to
            PublishFileAccessSummary(FileReadFailedCount, FileWriteFailedCount);

            // Publish command summary to console
            PublishCommandSummary(consoleCommand, grepResultCollection, FilesMatchedCount, DeleteSuccessCount, ReplacedSuccessCount);
        }