Skip to content

Commit 5cd97f6

Browse files
author
snzen
committed
+ replace
1 parent 649ebff commit 5cd97f6

File tree

3 files changed

+131
-2
lines changed

3 files changed

+131
-2
lines changed

FilesCore/Files.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
<ApplicationIcon />
88
<OutputType>Exe</OutputType>
99
<StartupObject />
10-
<AssemblyVersion>1.4.0.0</AssemblyVersion>
10+
<AssemblyVersion>1.5.0.0</AssemblyVersion>
1111
<FileVersion>1.3.0.0</FileVersion>
12-
<Version>1.4</Version>
12+
<Version>1.5</Version>
1313
<Authors>Arsuq</Authors>
1414
<Company>Arsuq</Company>
1515
<Description>File utils</Description>

FilesCore/Replace.cs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Text;
5+
using System.Text.RegularExpressions;
6+
7+
namespace Utils.Files
8+
{
9+
public class Replace : IUtil
10+
{
11+
public string Name => "replace";
12+
public string Info => "Replaces the matching text with a given string in all/some files in a folder. " + Environment.NewLine +
13+
"Args: interactive (-ni), source dir [default is current] (-src), search pattern [*.*] (-sp), " +
14+
"target regex (-reg), text to replace (-txt), ignore path regex [optional, Ex: (?:path\\A|path\\B)] (-ireg), " +
15+
"recursive [y/*] (-r)" + Environment.NewLine +
16+
@"Example converting CRLF line endings to LF: files -p replace -ni -src <dir> -reg (?:\r\n) -text \n" + Environment.NewLine +
17+
"Example normal text replacement: files -p replace -ni -src <dir> -reg \"text with spaces\" -text \"new text\"";
18+
19+
public int Run(RunArgs ra)
20+
{
21+
bool interactive = !ra.InArgs.ContainsKey("-ni");
22+
var text = string.Empty;
23+
var tf = string.Empty;
24+
var recursive = SearchOption.TopDirectoryOnly;
25+
var ignoreRegx = string.Empty;
26+
var targetRegx = string.Empty;
27+
28+
if (interactive)
29+
{
30+
var src = string.Empty;
31+
Utils.ReadString("Source folder: ", ref src);
32+
if (!string.IsNullOrEmpty(src)) ra.RootDir = new DirectoryInfo(src);
33+
Utils.ReadString("Search pattern (*.*): ", ref ra.State.SearchPattern);
34+
Utils.ReadString("Target regex: ", ref targetRegx);
35+
Utils.ReadString("Ignore regex: ", ref ignoreRegx);
36+
Utils.ReadString("Text: ", ref text);
37+
if (Utils.ReadWord("Recursive? (y/*): ", "y")) recursive = SearchOption.AllDirectories;
38+
}
39+
else
40+
{
41+
if (ra.InArgs.ContainsKey("-src")) ra.RootDir = new DirectoryInfo(ra.InArgs.GetFirstValue("-src"));
42+
if (ra.InArgs.ContainsKey("-sp")) ra.State.SearchPattern = ra.InArgs.GetFirstValue("-sp");
43+
if (ra.InArgs.ContainsKey("-reg")) targetRegx = ra.InArgs.GetFirstValue("-reg");
44+
if (ra.InArgs.ContainsKey("-ireg")) ignoreRegx = ra.InArgs.GetFirstValue("-ireg");
45+
if (ra.InArgs.ContainsKey("-text")) text = ra.InArgs.GetFirstValue("-text");
46+
if (ra.InArgs.ContainsKey("-r") && ra.InArgs.GetFirstValue("-r") == "y")
47+
recursive = SearchOption.AllDirectories;
48+
}
49+
50+
var F = new List<FileInfo>();
51+
var I = new List<FileInfo>();
52+
foreach (var file in ra.RootDir.EnumerateFiles(ra.State.SearchPattern, recursive))
53+
{
54+
if (!string.IsNullOrEmpty(ignoreRegx) && Regex.IsMatch(file.FullName, ignoreRegx)) I.Add(file);
55+
else F.Add(file);
56+
}
57+
58+
$"There are {F.Count + I.Count} files, {I.Count} ignored by a regex match".PrintLine(ConsoleColor.Yellow);
59+
60+
if (F.Count > 0)
61+
{
62+
if (interactive && Utils.ReadWord("Trace first? (y/*): ", "y"))
63+
{
64+
$"{Environment.NewLine}Files:".PrintLine();
65+
foreach (var f in F) $"{f.FullName}".PrintLine(ConsoleColor.DarkYellow);
66+
$"{Environment.NewLine}Ignored files:".PrintLine();
67+
foreach (var f in I) $"{f.FullName}".PrintLine(ConsoleColor.DarkRed);
68+
}
69+
70+
"".PrintLine();
71+
72+
if (interactive && !Utils.ReadWord("Edit? (y/*): ", "y")) return -1;
73+
74+
"".PrintLine();
75+
76+
var c = 0;
77+
text = Regex.Unescape(text);
78+
79+
foreach (var f in F)
80+
try
81+
{
82+
var allBytes = File.ReadAllBytes(f.FullName);
83+
var allText = Encoding.UTF8.GetString(allBytes);
84+
85+
if (allText != null && allText.Length > 0)
86+
{
87+
var r = Regex.Replace(allText, targetRegx, text);
88+
if (r != null)
89+
{
90+
allBytes = Encoding.UTF8.GetBytes(r);
91+
File.WriteAllBytes(f.FullName, allBytes);
92+
}
93+
}
94+
95+
var pl = string.Format("{0, 6}: {1}", ++c, f.FullName);
96+
pl.PrintLine(ConsoleColor.Green);
97+
}
98+
catch (Exception ex)
99+
{
100+
$"{f.FullName} ex: {ex.Message}".PrintSysError();
101+
}
102+
}
103+
104+
$"{Environment.NewLine}Done. {Environment.NewLine}".PrintLine(ConsoleColor.Yellow);
105+
106+
return 0;
107+
}
108+
}
109+
}

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,26 @@ files -p ext -ni -sp *.png -ext jpg
173173
Renames the matching files from the current folder with the names from a text
174174
file.
175175

176+
### replace
177+
Replaces the matching text with a given string in all/some files in a folder.
178+
Args:
179+
180+
interactive (-ni)
181+
source dir [default is current] (-src)
182+
search pattern [*.*] (-sp)
183+
target regex (-reg)
184+
text to replace (-txt)
185+
ignore path regex [optional, Ex: (?:path\A|path\B)] (-ireg)
186+
recursive [y/*] (-r)
187+
188+
Example converting CRLF line endings to LF:
189+
190+
files -p replace -ni -src <dir> -reg (?:\r\n) -text \n
191+
192+
Example normal text replacement:
193+
194+
files -p replace -ni -src <dir> -reg "text with spaces" -text "new text"
195+
176196
### search
177197
Search for files recursively.
178198
Args:

0 commit comments

Comments
 (0)