自己写了了个批量查找替换工具(C#),目前已知问题有查找速度不够快,假死现象等。
using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; /* author:wgscd date:2020-11-30 email:wgscd@126.com */ using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Collections.ObjectModel; using System.Windows.Forms; using System.Diagnostics; namespace ADFindAndReplace { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DATA_GRID.DataContext = resultList; } bool isReplace = false; bool includeSubFolder = false; string searchPattern = "*.*"; string replaceWords = ""; ObservableCollection<Result> resultList = new ObservableCollection<Result>(); private void btnSearch_Click(object sender, RoutedEventArgs e) { isReplace = false; doWork(); } private void btnReplace_Click(object sender, RoutedEventArgs e) { isReplace = true; replaceWords = txtReplace.Text; doWork(); } void doWork() { if (txtPath.Text.Trim() == "" || txtWords.Text == "" || txtFileType.Text.Trim() == "") { System.Windows.MessageBox.Show("please fill setting"); return; } if (isReplace) { if (txtReplace.Text == "") { return; } } includeSubFolder = (bool)ckSubfolder.IsChecked; searchPattern = txtFileType.Text; resultList.Clear(); string path = txtPath.Text.Trim(); string words = txtWords.Text; try { getFiles(path, words); } catch (Exception ex) { System.Windows.MessageBox.Show(ex.Message); } } void getFiles(string path, string words) { string[] fileList = new string[] { }; if (includeSubFolder) { fileList = Directory.GetFiles(path, searchPattern, SearchOption.AllDirectories); } else { fileList = Directory.GetFiles(path, searchPattern); } foreach (string f in fileList) { try { var str = File.ReadAllText(f); if (str.Contains(words)) { int i = str.IndexOf(words); resultList.Add(new Result() { FilePath = f, Briefwords = "" + str.PadLeft(8).PadRight(8).Substring(i - 8, 8 + words.Length) }); if (isReplace) { File.WriteAllText(f, str.Replace(words, replaceWords)); } } } catch (Exception ex) { Debug.Print(ex.Message); } } } private void btnSelectFolder_Click(object sender, RoutedEventArgs e) { FolderBrowserDialog df = new FolderBrowserDialog(); //df.Description = "select path"; df.ShowNewFolderButton = false; DialogResult result = df.ShowDialog(); if (result == System.Windows.Forms.DialogResult.OK) { txtPath.Text = df.SelectedPath; } } } public class Result : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private string filePath { get; set; } private string briefwords { get; set; } private int lineNumber { get; set; } public string FilePath { get { return filePath; } set { filePath = value; NotifyChanged("FilePath"); } } public string Briefwords { get { return briefwords; } set { briefwords = value; NotifyChanged("Briefwords"); } } public int LineNumber { get { return lineNumber; } set { lineNumber = value; NotifyChanged("LineNumber"); } } void NotifyChanged(string propName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propName)); } } } }
<Window x:Class="ADFindAndReplace.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:ADFindAndReplace" mc:Ignorable="d" Title="ADFindAndReplace" Height="450" Width="883"> <Grid> <Label HorizontalAlignment="Left" Height="23" Margin="0,21,0,0" Content="serach words:" VerticalAlignment="Top" Width="90"/> <TextBox x:Name="txtWords" HorizontalAlignment="Left" Height="23" Margin="113,21,0,0" TextWrapping="Wrap" Text="wgscd" VerticalAlignment="Top" Width="551"/> <Label HorizontalAlignment="Left" Height="23" Margin="10,51,0,0" Content="serach Path:" VerticalAlignment="Top" Width="90"/> <TextBox x:Name="txtPath" HorizontalAlignment="Left" Height="23" Margin="113,51,0,0" TextWrapping="Wrap" Text="c:" VerticalAlignment="Top" Width="200"/> <Button x:Name="btnSelectFolder" HorizontalAlignment="Left" Height="21" Margin="318,53,0,0" Content="...Bowser" VerticalAlignment="Top" Width="60" Click="btnSelectFolder_Click"/> <CheckBox x:Name="ckSubfolder" VerticalContentAlignment="Center" HorizontalAlignment="Left" Height="23" Margin="392,51,0,0" Content="include sub folders" VerticalAlignment="Top" Width="134"/> <Label HorizontalAlignment="Left" Height="25" Margin="531,53,0,0" Content="File Type:" VerticalAlignment="Top" Width="60"/> <TextBox x:Name="txtFileType" ToolTip="*.*;*.txt;*.doc etc.." Text="*.*" HorizontalAlignment="Left" Height="23" Margin="611,55,0,0" VerticalAlignment="Top" Width="53"> </TextBox> <Label HorizontalAlignment="Left" Height="23" Margin="10,88,0,0" Content="Replace Words:" VerticalAlignment="Top" Width="90"/> <TextBox x:Name="txtReplace" HorizontalAlignment="Left" Height="23" Margin="113,88,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="225"/> <Button x:Name="btnSearch" Content="Search" HorizontalAlignment="Left" Margin="688,13,0,0" VerticalAlignment="Top" Width="104" Height="42" Click="btnSearch_Click"/> <Button x:Name="btnReplace" Content="Replace" HorizontalAlignment="Left" Margin="688,73,0,0" VerticalAlignment="Top" Width="104" Height="38" Click="btnReplace_Click"/> <DataGrid x:Name="DATA_GRID" ItemsSource="{Binding}" AutoGenerateColumns="False" Margin="0,128,0,34"> <DataGrid.Columns> <DataGridTextColumn Header="file" Binding="{Binding FilePath}" MinWidth="422"/> <DataGridTextColumn Header="Briefwords" Binding="{Binding Briefwords}"/> </DataGrid.Columns> </DataGrid> <Label Name="lbState" Height="29" Content="Ready" VerticalAlignment="Bottom"/> </Grid> </Window>