public CommandResult <(List <FileSystemPath> items, FindCounts counts)> Find( CommandEvaluationContext context, [Parameter("search target: can be a folder or a file. If target is a file, the command must have a -c|--contains parameter (search in file)")] FileSystemPath path, [Option("p", "pattern", "select names that matches the pattern", true, true)] string pattern, [Option("i", "non-sensitive", "if set and p is set, perform a non case sensisitive search")] bool ignoreCase, [Option("f", "fullname", "check pattern on fullname instead of name")] bool checkPatternOnFullName, [Option("c", "contains", "files that contains the string", true, true)] string contains, [Option("a", "attr", "print file system attributes")] bool attributes, [Option("s", "short", "print short pathes")] bool shortPathes, [Option("l", "all", "select both files and directories")] bool all, [Option("d", "dir", "select only directories")] bool dirs, [Option("t", "top", "search in top directory only")] bool top, [Option("m", "matches", "print matches lines if c|--contains")] bool matches ) { if (path.CheckExists(context)) { var sp = string.IsNullOrWhiteSpace(pattern) ? "*" : pattern; var counts = new FindCounts(); var items = FindItems(context, path.FullName, sp, top, all, dirs, attributes, shortPathes, contains, checkPatternOnFullName, counts, true, false, ignoreCase, matches); var f = DefaultForegroundCmd; counts.Elapsed = DateTime.Now - counts.BeginDateTime; if (items.Count > 0) { context.Out.Echoln(); } context.Out.Echoln($"found {context.ShellEnv.Colors.Numeric}{Plur("file", counts.FilesCount, f)} and {context.ShellEnv.Colors.Numeric}{Plur("folder", counts.FoldersCount, f)}. scanned {context.ShellEnv.Colors.Numeric}{Plur("file", counts.ScannedFilesCount, f)} in {context.ShellEnv.Colors.Numeric}{Plur("folder", counts.ScannedFoldersCount, f)} during {TimeSpanDescription(counts.Elapsed, context.ShellEnv.Colors.Numeric.ToString(), f)}"); return(new CommandResult <(List <FileSystemPath>, FindCounts)>((items, counts))); } return(new CommandResult <(List <FileSystemPath>, FindCounts)>((new List <FileSystemPath>(), new FindCounts()), ReturnCode.Error)); }
public CommandResult <(List <(FileSystemPath source, FileSystemPath target)> items, FindCounts counts)> Mv( CommandEvaluationContext context, [Parameter("source: file/directory or several corresponding to a wildcarded path")] WildcardFilePath source, [Parameter(1, "destination: a file or a directory")] FileSystemPath dest, [Option("i", "prompt before overwrite")] bool interactive, [Option("v", "explain what is being done")] bool verbose ) { if (source.CheckExists()) { var counts = new FindCounts(); var items = FindItems(context, source.FullName, source.WildCardFileName ?? "*", true, true, false, true, false, null, false, counts, false, false); var sourceCount = items.Count; List <(FileSystemPath src, FileSystemPath tgt)> r = new List <(FileSystemPath src, FileSystemPath tgt)>(); if (sourceCount > 1) { if (dest.CheckExists()) { if (!dest.IsDirectory) { Errorln("dest must be a directory"); return(new CommandResult <(List <(FileSystemPath, FileSystemPath)> items, FindCounts counts)>( (new List <(FileSystemPath, FileSystemPath)> { (source, dest) }, counts), ReturnCode.Error )); } else { // move multiple source to dest foreach (var item in items) { var msg = $"move {item.GetPrintableName()} to {dest.GetPrintableName()}"; if (!interactive || Confirm("mv: " + msg)) { if (source.IsFile) { var newdest = Path.Combine(dest.FullName, item.Name); r.Add((item, new FileSystemPath(newdest))); File.Move(item.FullName, newdest); } else { var newdest = Path.Combine(dest.FullName, item.Name); Directory.Move(item.FullName, newdest); r.Add((item, new DirectoryPath(newdest))); } if (verbose) { context.Out.Echoln(msg.Replace("move ", "moved ")); } } } } } } else { if (dest.CheckExists(false)) { if (dest.IsDirectory) { // move one source to dest var msg = $"move {source.GetPrintableNameWithWlidCard()} to {dest.GetPrintableName()}"; if (!interactive || Confirm("mv: " + msg)) { if (source.IsFile) { var newdest = Path.Combine(dest.FullName, source.NameWithWildcard); File.Move(source.FullNameWithWildcard, newdest); r.Add((new FilePath(source.FullNameWithWildcard), new FilePath(newdest))); } else { var newdest = Path.Combine(dest.FullName, source.NameWithWildcard); Directory.Move(source.FullName, newdest); r.Add((source, new DirectoryPath(newdest))); } if (verbose) { context.Out.Echoln(msg.Replace("move ", "moved ")); } } } else { // rename source (file) to dest (overwrite dest) var msg = $"rename {source.GetPrintableNameWithWlidCard()} to {dest.GetPrintableName()}"; if (!interactive || Confirm("mv: " + msg)) { dest.FileSystemInfo.Delete(); File.Move(source.FullNameWithWildcard, dest.FullName); r.Add((new FilePath(source.FullNameWithWildcard), dest)); if (verbose) { context.Out.Echoln(msg.Replace("rename ", "renamed ")); } } } } else { // rename source to dest var msg = $"rename {source.GetPrintableNameWithWlidCard()} to {dest.GetPrintableName()}"; if (!interactive || Confirm("mv: " + msg)) { if (source.IsFile) { File.Move(source.FullNameWithWildcard, dest.FullName); r.Add((new FilePath(source.FullNameWithWildcard), dest)); } else { Directory.Move(source.FullName, dest.FullName); r.Add((source, dest)); } if (verbose) { context.Out.Echoln(msg.Replace("rename ", "renamed ")); } } } } return(new CommandResult <(List <(FileSystemPath source, FileSystemPath target)> items, FindCounts counts)> ((r, counts))); } else { return(new CommandResult <(List <(FileSystemPath, FileSystemPath)> items, FindCounts counts)> ((new List <(FileSystemPath, FileSystemPath)> { (source, null) }, new FindCounts()))); } }
public CommandResult <List <FilePath> > CheckIntegrity( CommandEvaluationContext context, [Parameter("path of a file to be checked or path from where find files to to be checked")] FileSystemPath fileOrDir, [Option("p", "pattern", "select names that matches the pattern", true, true)] string pattern, [Option("i", "non-sensitive", "if set and p is set, perform a non case sensisitive search")] bool ignoreCase, [Option("a", "attr", "print file system attributes")] bool printAttr, [Option("t", "top", "search in top directory only")] bool top, [Option("q", "quiet", "quiet mode: do not print error message below corrupted file name")] bool quiet, [Option("r", "ratio", "acceptable ratio of non printable characters", true, true)] double ratio = 30, [Option("s", "min-size", "minimum size of analysed part of the text", true, true)] int minSeqLength = 1024 ) { var r = new List <FilePath>(); if (fileOrDir.CheckExists(context)) { if (fileOrDir.IsFile) { var(isValid, filePath) = CheckIntegrity(context, new FilePath(fileOrDir.FullName), ratio, printAttr, minSeqLength, quiet); if (!isValid) { r.Add(filePath); } return(new CommandResult <List <FilePath> >(r)); } else { var sp = string.IsNullOrWhiteSpace(pattern) ? "*" : pattern; var counts = new FindCounts(); var items = FindItems(context, fileOrDir.FullName, sp, top, false, false, printAttr, false, null, false, counts, false, false, ignoreCase); var f = context.ShellEnv.Colors.Default.ToString(); var elapsed = DateTime.Now - counts.BeginDateTime; context.Out.Echoln($"found {context.ShellEnv.Colors.Numeric}{Plur("file", counts.FilesCount, f)} and {context.ShellEnv.Colors.Numeric}{Plur("folder", counts.FoldersCount, f)}. scanned {context.ShellEnv.Colors.Numeric}{Plur("file", counts.ScannedFilesCount, f)} in {context.ShellEnv.Colors.Numeric}{Plur("folder", counts.ScannedFoldersCount, f)} during {TimeSpanDescription(elapsed, context.ShellEnv.Colors.Numeric.ToString(), f)}"); if (items.Count > 0) { context.Out.Echoln($"analyzing files ({counts.FilesCount})..."); int corruptedFilesCount = 0; foreach (var item in items) { if (context.CommandLineProcessor.CancellationTokenSource.Token.IsCancellationRequested) { break; } if (item.IsFile) { if (!CheckIntegrity(context, (FilePath)item, ratio, printAttr, minSeqLength, quiet).isValid) { corruptedFilesCount++; r.Add((FilePath)item); } } } if (corruptedFilesCount > 0) { context.Out.Echoln(); } var crprt = (double)corruptedFilesCount / (double)counts.FilesCount * 100d; context.Out.Echoln($"found {context.ShellEnv.Colors.Numeric}{Plur("corrupted file", corruptedFilesCount, f)} in {context.ShellEnv.Colors.Numeric}{Plur("file", counts.FilesCount, f)} corruption ratio={Cyan}{crprt}%"); return(new CommandResult <List <FilePath> >(r)); } else { return(new CommandResult <List <FilePath> >(r)); } } } else { return(new CommandResult <List <FilePath> >(new List <FilePath> { new FilePath(fileOrDir.FullName) }, ReturnCode.Error)); } }