(view source code of locase.cs as plain text)
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Win32;
namespace RobvanderWoude
{
class LoCase
{
public static string progver = "2.04";
static int Main( string[] args )
{
bool ignoreerrors = false;
bool verbose = false;
char[] upcaseletters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray( );
int start = 0;
int length = 0;
List<string> files = new List<string>( );
List<string> errors = new List<string>( );
#region Command Line Parsing
int namedargscount = 0;
int unnamedargscount = 0;
bool startspecified = false;
foreach ( string arg in args )
{
if ( arg[0] == '/' )
{
namedargscount++;
switch ( arg.ToUpper( )[1] )
{
case '?':
return ShowHelp( );
case 'I':
if ( ignoreerrors )
{
return ShowHelp( "Duplicate command line switch /I" );
}
ignoreerrors = true;
break;
case 'L':
if ( length > 0 )
{
return ShowHelp( "Duplicate command line switch /L" );
}
if ( arg.Length < 4 || arg[2] != ':' || !int.TryParse( arg.Substring( 3 ), out length ) || length < 1 )
{
return ShowHelp( "Invalid length specified: \"{0}\"", arg );
}
break;
case 'S':
if ( start > 0 )
{
return ShowHelp( "Duplicate command line switch /S" );
}
if ( arg.Length < 4 || arg[2] != ':' || !int.TryParse( arg.Substring( 3 ), out start ) || start < 0 )
{
return ShowHelp( "Invalid start specified: \"{0}\"", arg );
}
startspecified = true;
break;
case 'V':
if ( verbose )
{
return ShowHelp( "Duplicate command line switch /V" );
}
verbose = true;
break;
default:
return ShowHelp( "Invalid command line switch \"{0}\"", arg );
}
}
else
{
unnamedargscount++;
string parentfolder = Directory.GetParent( arg ).FullName;
if ( !Directory.Exists( parentfolder ) )
{
return ShowHelp( "Invalid parent folder \"{0}\"", parentfolder );
}
string filespec = Path.GetFileName( arg );
foreach ( string file in Directory.GetFiles( parentfolder, filespec ) )
{
if ( Path.GetFileName( file ).IndexOfAny( upcaseletters ) > -1 )
{
if ( !files.Contains( file ) )
{
files.Add( file );
}
}
}
}
}
if ( Console.IsInputRedirected && unnamedargscount > 0 )
{
return ShowHelp( "Either use redirected input or specify files, but not both" );
}
if ( !startspecified && length > 0 )
{
return ShowHelp( "You need to specify a start value with /S if /L is used" );
}
#endregion Command Line Parsing
if ( Console.IsInputRedirected )
{
#region Convert redirected input to lower case
string input = Console.In.ReadToEnd( );
string output = string.Empty;
if ( start != 0 || length != 0 )
{
if ( start > 0 )
{
output = input.Substring( 0, start );
}
if ( length > 0 && start + length < input.Length )
{
output += input.Substring( start, length ).ToLowerInvariant( );
output += input.Substring( start + length );
}
else
{
output += input.Substring( start ).ToLowerInvariant( );
}
}
else
{
output = input.ToLowerInvariant( );
}
Console.Write( output );
return 0;
#endregion Convert redirected input to lower case
}
else
{
#region Rename files to lower case
foreach ( string file in files )
{
if ( File.Exists( file ) )
{
string parentfolder = Directory.GetParent( file ).FullName;
string filename = Path.GetFileName( file );
if ( filename.IndexOfAny( upcaseletters ) > -1 )
{
string newfilename = string.Empty;
if ( start != 0 || length != 0 )
{
if ( start > 0 )
{
newfilename = filename.Substring( 0, start );
}
if ( start + length < filename.Length )
{
newfilename += filename.Substring( start, length ).ToLowerInvariant( );
newfilename += filename.Substring( start + length );
}
else
{
newfilename += filename.Substring( start ).ToLowerInvariant( );
}
}
else
{
newfilename = filename.ToLowerInvariant( );
}
newfilename = Path.Combine( parentfolder, newfilename );
try
{
if ( verbose )
{
Console.WriteLine( "\"{0}\" => \"{1}\"", file, newfilename );
}
File.Move( file, newfilename );
}
catch ( Exception e )
{
Console.Error.WriteLine( "Error renaming \"{0}\": {1}", filename, e.Message );
if ( !ignoreerrors )
{
return -1;
}
errors.Add( filename );
}
}
}
else
{
if ( ignoreerrors )
{
return -1;
}
errors.Add( Path.GetFullPath( file ) );
}
}
if ( verbose )
{
Console.WriteLine( "{0} matching file{1} renamed", ( files.Count == 0 ? "No" : files.Count.ToString( ) ), ( files.Count == 1 ? String.Empty : "s" ) );
}
if ( ignoreerrors )
{
if ( verbose && errors.Count > 0 )
{
if ( errors.Count == 1 )
{
Console.Error.WriteLine( "An error occurred while renaming the following file:" );
Console.Error.WriteLine( "====================================================" );
}
else
{
Console.Error.WriteLine( "Errors occurred while renaming the following files:" );
Console.Error.WriteLine( "===================================================" );
}
foreach ( string error in errors )
{
Console.Error.WriteLine( error );
}
}
return errors.Count;
}
else
{
return files.Count;
}
#endregion Rename files to lower case
}
}
public static int ShowHelp( params string[] errmsg )
{
#region Error Message
if ( errmsg.Length > 0 )
{
List<string> errargs = new List<string>( errmsg );
errargs.RemoveAt( 0 );
Console.Error.WriteLine( );
Console.ForegroundColor = ConsoleColor.Red;
Console.Error.Write( "ERROR:\t" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( errmsg[0], errargs.ToArray( ) );
Console.ResetColor( );
}
#endregion Error Message
#region Help Text
/*
LoCase.exe, Version 2.03
Either rename specified files or render redirected input to lower case
Usage: LOCASE.EXE [ filespec [ filespec [ ... ] ] ] [ options ]
or: somecommand | LOCASE.EXE
Where: filespec file(s) to be renamed (wildcards allowed, default: *.*)
somecommand command whose output will be rendered to lower case
Options: /I Ignore file IO errors and continue (see Notes)
/S:n [ /L:m ] modify only the substring Starting at n with Length m
(default: entire string; default length: until end)
/V Verbose mode: displays file renaming and files count
Notes: Use doublequotes if filespec contains non-alphnumeric characters.
If no folder is specified in filespec, current directory is assumed.
Return code (\"ErrorLevel\") equals the number of renamed files,
or the number of errors if /I is used, or -1 in case /I is not
used and an error occurred.
Example: LOCASE D:\folder\MYFILE.TXT /S:1
will rename "D:\folder\MYFILE.TXT" to "D:\folder\Myfile.txt"
Example: LOCASE D:\folder\MYFILE.TXT /S:0 /L:2
will rename "D:\folder\MYFILE.TXT" to "D:\folder\myFILE.TXT"
Written by Rob van der Woude
https://www.robvanderwoude.com
*/
#endregion Help Text
#region Display Help Text
Console.Error.WriteLine( );
Console.Error.WriteLine( "LoCase.exe, Version {0}", progver );
Console.Error.WriteLine( "Either rename specified files or render redirected input to lower case" );
Console.Error.WriteLine( );
Console.Error.Write( "Usage: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( "LOCASE.EXE [ filespec [ filespec [ ... ] ] ] [ options ]" );
Console.ResetColor( );
Console.Error.WriteLine( );
Console.Error.Write( "or: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( "somecommand | LOCASE.EXE" );
Console.ResetColor( );
Console.Error.WriteLine( );
Console.Error.Write( "Where: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "filespec" );
Console.ResetColor( );
Console.Error.WriteLine( " file(s) to be renamed (wildcards allowed, default: *.*)" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " somecommand" );
Console.ResetColor( );
Console.Error.WriteLine( " command whose output will be rendered to lower case" );
Console.Error.Write( "Options: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "/I I" );
Console.ResetColor( );
Console.Error.WriteLine( "gnore file IO errors and continue (see Notes)" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " /S:n [ /L:m ]" );
Console.ResetColor( );
Console.Error.Write( " modify only the substring " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "S" );
Console.ResetColor( );
Console.Error.Write( "tarting at " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "n" );
Console.ResetColor( );
Console.Error.Write( " with " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "L" );
Console.ResetColor( );
Console.Error.Write( "ength " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( "m" );
Console.ResetColor( );
Console.Error.WriteLine( " (default: entire string; default length: until end)" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " /V V" );
Console.ResetColor( );
Console.Error.WriteLine( "erbose mode: displays file renaming and files count" );
Console.Error.WriteLine( );
Console.Error.WriteLine( "Notes: Use doublequotes if filespec contains non-alphnumeric characters." );
Console.Error.WriteLine( " If no folder is specified in filespec, current directory is assumed." );
Console.Error.WriteLine( " Return code (\"ErrorLevel\") equals the number of renamed files," );
Console.Error.WriteLine( " or the number of errors if /I is used, or -1 in case /I is not" );
Console.Error.WriteLine( " used and an error occurred." );
Console.Error.WriteLine( );
Console.Error.Write( "Example: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( "LOCASE D:\\folder\\MYFILE.TXT /S:1" );
Console.ResetColor( );
Console.Error.Write( " will rename \"D:\\folder\\MYFILE.TXT\" to \"D:\\folder\\M" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( "yfile.txt\"" );
Console.ResetColor( );
Console.Error.WriteLine( );
Console.Error.Write( "Example: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( "LOCASE D:\\folder\\MYFILE.TXT /S:0 /L:2" );
Console.ResetColor( );
Console.Error.Write( " will rename \"D:\\folder\\MYFILE.TXT\" to \"D:\\folder\\" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "my" );
Console.ResetColor( );
Console.Error.WriteLine( "FILE.TXT\"" );
Console.Error.WriteLine( );
Console.Error.WriteLine( "Written by Rob van der Woude" );
Console.Error.WriteLine( "https://www.robvanderwoude.com" );
#endregion Display Help Text
return -1;
}
}
}
page last modified: 2024-04-16; loaded in 0.0112 seconds