Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for locase.cs

(view source code of locase.cs as plain text)

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using Microsoft.Win32;
  5.  
  6.  
  7. namespace RobvanderWoude
  8. {
  9. 	class LoCase
  10. 	{
  11. 		public static string progver = "2.04";
  12.  
  13.  
  14. 		static int Main( string[] args )
  15. 		{
  16. 			bool ignoreerrors = false;
  17. 			bool verbose = false;
  18. 			char[] upcaseletters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray( );
  19. 			int start = 0;
  20. 			int length = 0;
  21. 			List<string> files = new List<string>( );
  22. 			List<string> errors = new List<string>( );
  23.  
  24.  
  25. 			#region Command Line Parsing
  26.  
  27. 			int namedargscount = 0;
  28. 			int unnamedargscount = 0;
  29. 			bool startspecified = false;
  30. 			foreach ( string arg in args )
  31. 			{
  32. 				if ( arg[0] == '/' )
  33. 				{
  34. 					namedargscount++;
  35. 					switch ( arg.ToUpper( )[1] )
  36. 					{
  37. 						case '?':
  38. 							return ShowHelp( );
  39. 						case 'I':
  40. 							if ( ignoreerrors )
  41. 							{
  42. 								return ShowHelp( "Duplicate command line switch /I" );
  43. 							}
  44. 							ignoreerrors = true;
  45. 							break;
  46. 						case 'L':
  47. 							if ( length > 0 )
  48. 							{
  49. 								return ShowHelp( "Duplicate command line switch /L" );
  50. 							}
  51. 							if ( arg.Length < 4 || arg[2] != ':' || !int.TryParse( arg.Substring( 3 ), out length ) || length < 1 )
  52. 							{
  53. 								return ShowHelp( "Invalid length specified: \"{0}\"", arg );
  54. 							}
  55. 							break;
  56. 						case 'S':
  57. 							if ( start > 0 )
  58. 							{
  59. 								return ShowHelp( "Duplicate command line switch /S" );
  60. 							}
  61. 							if ( arg.Length < 4 || arg[2] != ':' || !int.TryParse( arg.Substring( 3 ), out start ) || start < 0 )
  62. 							{
  63. 								return ShowHelp( "Invalid start specified: \"{0}\"", arg );
  64. 							}
  65. 							startspecified = true;
  66. 							break;
  67. 						case 'V':
  68. 							if ( verbose )
  69. 							{
  70. 								return ShowHelp( "Duplicate command line switch /V" );
  71. 							}
  72. 							verbose = true;
  73. 							break;
  74. 						default:
  75. 							return ShowHelp( "Invalid command line switch \"{0}\"", arg );
  76. 					}
  77. 				}
  78. 				else
  79. 				{
  80. 					unnamedargscount++;
  81. 					string parentfolder = Directory.GetParent( arg ).FullName;
  82. 					if ( !Directory.Exists( parentfolder ) )
  83. 					{
  84. 						return ShowHelp( "Invalid parent folder \"{0}\"", parentfolder );
  85. 					}
  86. 					string filespec = Path.GetFileName( arg );
  87. 					foreach ( string file in Directory.GetFiles( parentfolder, filespec ) )
  88. 					{
  89. 						if ( Path.GetFileName( file ).IndexOfAny( upcaseletters ) > -1 )
  90. 						{
  91. 							if ( !files.Contains( file ) )
  92. 							{
  93. 								files.Add( file );
  94. 							}
  95. 						}
  96. 					}
  97. 				}
  98. 			}
  99.  
  100. 			if ( Console.IsInputRedirected && unnamedargscount > 0 )
  101. 			{
  102. 				return ShowHelp( "Either use redirected input or specify files, but not both" );
  103. 			}
  104.  
  105. 			if ( !startspecified && length > 0 )
  106. 			{
  107. 				return ShowHelp( "You need to specify a start value with /S if /L is used" );
  108. 			}
  109.  
  110. 			#endregion Command Line Parsing
  111.  
  112.  
  113. 			if ( Console.IsInputRedirected )
  114. 			{
  115. 				#region Convert redirected input to lower case
  116.  
  117. 				string input = Console.In.ReadToEnd( );
  118. 				string output = string.Empty;
  119. 				if ( start != 0 || length != 0 )
  120. 				{
  121. 					if ( start > 0 )
  122. 					{
  123. 						output = input.Substring( 0, start );
  124. 					}
  125. 					if ( length > 0 && start + length < input.Length )
  126. 					{
  127. 						output += input.Substring( start, length ).ToLowerInvariant( );
  128. 						output += input.Substring( start + length );
  129. 					}
  130. 					else
  131. 					{
  132. 						output += input.Substring( start ).ToLowerInvariant( );
  133. 					}
  134. 				}
  135. 				else
  136. 				{
  137. 					output = input.ToLowerInvariant( );
  138. 				}
  139. 				Console.Write( output );
  140. 				return 0;
  141.  
  142. 				#endregion Convert redirected input to lower case
  143. 			}
  144. 			else
  145. 			{
  146. 				#region Rename files to lower case
  147.  
  148. 				foreach ( string file in files )
  149. 				{
  150. 					if ( File.Exists( file ) )
  151. 					{
  152. 						string parentfolder = Directory.GetParent( file ).FullName;
  153. 						string filename = Path.GetFileName( file );
  154. 						if ( filename.IndexOfAny( upcaseletters ) > -1 )
  155. 						{
  156. 							string newfilename = string.Empty;
  157. 							if ( start != 0 || length != 0 )
  158. 							{
  159. 								if ( start > 0 )
  160. 								{
  161. 									newfilename = filename.Substring( 0, start );
  162. 								}
  163. 								if ( start + length < filename.Length )
  164. 								{
  165. 									newfilename += filename.Substring( start, length ).ToLowerInvariant( );
  166. 									newfilename += filename.Substring( start + length );
  167. 								}
  168. 								else
  169. 								{
  170. 									newfilename += filename.Substring( start ).ToLowerInvariant( );
  171. 								}
  172. 							}
  173. 							else
  174. 							{
  175. 								newfilename = filename.ToLowerInvariant( );
  176. 							}
  177. 							newfilename = Path.Combine( parentfolder, newfilename );
  178. 							try
  179. 							{
  180. 								if ( verbose )
  181. 								{
  182. 									Console.WriteLine( "\"{0}\"  =>  \"{1}\"", file, newfilename );
  183. 								}
  184. 								File.Move( file, newfilename );
  185. 							}
  186. 							catch ( Exception e )
  187. 							{
  188. 								Console.Error.WriteLine( "Error renaming \"{0}\": {1}", filename, e.Message );
  189. 								if ( !ignoreerrors )
  190. 								{
  191. 									return -1;
  192. 								}
  193. 								errors.Add( filename );
  194. 							}
  195. 						}
  196. 					}
  197. 					else
  198. 					{
  199. 						if ( ignoreerrors )
  200. 						{
  201. 							return -1;
  202. 						}
  203. 						errors.Add( Path.GetFullPath( file ) );
  204. 					}
  205. 				}
  206. 				if ( verbose )
  207. 				{
  208. 					Console.WriteLine( "{0} matching file{1} renamed", ( files.Count == 0 ? "No" : files.Count.ToString( ) ), ( files.Count == 1 ? String.Empty : "s" ) );
  209. 				}
  210.  
  211. 				if ( ignoreerrors )
  212. 				{
  213. 					if ( verbose && errors.Count > 0 )
  214. 					{
  215. 						if ( errors.Count == 1 )
  216. 						{
  217. 							Console.Error.WriteLine( "An error occurred while renaming the following file:" );
  218. 							Console.Error.WriteLine( "====================================================" );
  219. 						}
  220. 						else
  221. 						{
  222. 							Console.Error.WriteLine( "Errors occurred while renaming the following files:" );
  223. 							Console.Error.WriteLine( "===================================================" );
  224. 						}
  225. 						foreach ( string error in errors )
  226. 						{
  227. 							Console.Error.WriteLine( error );
  228. 						}
  229. 					}
  230. 					return errors.Count;
  231. 				}
  232. 				else
  233. 				{
  234. 					return files.Count;
  235. 				}
  236.  
  237. 				#endregion Rename files to lower case
  238. 			}
  239. 		}
  240.  
  241.  
  242. 		public static int ShowHelp( params string[] errmsg )
  243. 		{
  244. 			#region Error Message
  245.  
  246. 			if ( errmsg.Length > 0 )
  247. 			{
  248. 				List<string> errargs = new List<string>( errmsg );
  249. 				errargs.RemoveAt( 0 );
  250. 				Console.Error.WriteLine( );
  251. 				Console.ForegroundColor = ConsoleColor.Red;
  252. 				Console.Error.Write( "ERROR:\t" );
  253. 				Console.ForegroundColor = ConsoleColor.White;
  254. 				Console.Error.WriteLine( errmsg[0], errargs.ToArray( ) );
  255. 				Console.ResetColor( );
  256. 			}
  257.  
  258. 			#endregion Error Message
  259.  
  260.  
  261. 			#region Help Text
  262.  
  263. 			/*
  264. 			LoCase.exe,  Version 2.03
  265. 			Either rename specified files or render redirected input to lower case
  266.  
  267. 			Usage:    LOCASE.EXE  [ filespec  [ filespec  [ ... ] ] ]  [ options ]
  268.  
  269. 			or:       somecommand  |  LOCASE.EXE
  270.  
  271. 			Where:    filespec      file(s) to be renamed (wildcards allowed, default: *.*)
  272. 			          somecommand   command whose output will be rendered to lower case
  273.  
  274. 			Options:  /I            Ignore file IO errors and continue (see Notes)
  275. 			          /S:n [ /L:m ] modify only the substring Starting at n with Length m
  276. 			                        (default: entire string; default length: until end)
  277. 			          /V            Verbose mode: displays file renaming and files count
  278.  
  279. 			Notes:    Use doublequotes if filespec contains non-alphnumeric characters.
  280. 			          If no folder is specified in filespec, current directory is assumed.
  281. 			          Return code (\"ErrorLevel\") equals the number of renamed files,
  282. 			          or the number of errors if /I is used, or -1 in case /I is not
  283. 			          used and an error occurred.
  284.  
  285. 			Example:  LOCASE D:\folder\MYFILE.TXT /S:1
  286. 			          will rename "D:\folder\MYFILE.TXT" to "D:\folder\Myfile.txt"
  287.  
  288. 			Example:  LOCASE D:\folder\MYFILE.TXT /S:0 /L:2
  289. 			          will rename "D:\folder\MYFILE.TXT" to "D:\folder\myFILE.TXT"
  290.  
  291. 			Written by Rob van der Woude
  292. 			https://www.robvanderwoude.com
  293. 			*/
  294.  
  295. 			#endregion Help Text
  296.  
  297.  
  298. 			#region Display Help Text
  299.  
  300. 			Console.Error.WriteLine( );
  301.  
  302. 			Console.Error.WriteLine( "LoCase.exe,  Version {0}", progver );
  303.  
  304. 			Console.Error.WriteLine( "Either rename specified files or render redirected input to lower case" );
  305.  
  306. 			Console.Error.WriteLine( );
  307.  
  308. 			Console.Error.Write( "Usage:    " );
  309. 			Console.ForegroundColor = ConsoleColor.White;
  310. 			Console.Error.WriteLine( "LOCASE.EXE  [ filespec  [ filespec  [ ... ] ] ]  [ options ]" );
  311. 			Console.ResetColor( );
  312.  
  313. 			Console.Error.WriteLine( );
  314.  
  315. 			Console.Error.Write( "or:       " );
  316. 			Console.ForegroundColor = ConsoleColor.White;
  317. 			Console.Error.WriteLine( "somecommand  |  LOCASE.EXE" );
  318. 			Console.ResetColor( );
  319.  
  320. 			Console.Error.WriteLine( );
  321.  
  322. 			Console.Error.Write( "Where:    " );
  323. 			Console.ForegroundColor = ConsoleColor.White;
  324. 			Console.Error.Write( "filespec" );
  325. 			Console.ResetColor( );
  326. 			Console.Error.WriteLine( "      file(s) to be renamed (wildcards allowed, default: *.*)" );
  327.  
  328. 			Console.ForegroundColor = ConsoleColor.White;
  329. 			Console.Error.Write( "          somecommand" );
  330. 			Console.ResetColor( );
  331. 			Console.Error.WriteLine( "   command whose output will be rendered to lower case" );
  332.  
  333. 			Console.Error.Write( "Options:  " );
  334. 			Console.ForegroundColor = ConsoleColor.White;
  335. 			Console.Error.Write( "/I            I" );
  336. 			Console.ResetColor( );
  337. 			Console.Error.WriteLine( "gnore file IO errors and continue (see Notes)" );
  338.  
  339. 			Console.ForegroundColor = ConsoleColor.White;
  340. 			Console.Error.Write( "          /S:n [ /L:m ]" );
  341. 			Console.ResetColor( );
  342. 			Console.Error.Write( " modify only the substring " );
  343. 			Console.ForegroundColor = ConsoleColor.White;
  344. 			Console.Error.Write( "S" );
  345. 			Console.ResetColor( );
  346. 			Console.Error.Write( "tarting at " );
  347. 			Console.ForegroundColor = ConsoleColor.White;
  348. 			Console.Error.Write( "n" );
  349. 			Console.ResetColor( );
  350. 			Console.Error.Write( " with " );
  351. 			Console.ForegroundColor = ConsoleColor.White;
  352. 			Console.Error.Write( "L" );
  353. 			Console.ResetColor( );
  354. 			Console.Error.Write( "ength " );
  355. 			Console.ForegroundColor = ConsoleColor.White;
  356. 			Console.Error.WriteLine( "m" );
  357. 			Console.ResetColor( );
  358.  
  359. 			Console.Error.WriteLine( "                        (default: entire string; default length: until end)" );
  360.  
  361. 			Console.ForegroundColor = ConsoleColor.White;
  362. 			Console.Error.Write( "           /V           V" );
  363. 			Console.ResetColor( );
  364. 			Console.Error.WriteLine( "erbose mode: displays file renaming and files count" );
  365.  
  366. 			Console.Error.WriteLine( );
  367.  
  368. 			Console.Error.WriteLine( "Notes:    Use doublequotes if filespec contains non-alphnumeric characters." );
  369.  
  370. 			Console.Error.WriteLine( "          If no folder is specified in filespec, current directory is assumed." );
  371.  
  372. 			Console.Error.WriteLine( "          Return code (\"ErrorLevel\") equals the number of renamed files," );
  373.  
  374. 			Console.Error.WriteLine( "          or the number of errors if /I is used, or -1 in case /I is not" );
  375.  
  376. 			Console.Error.WriteLine( "          used and an error occurred." );
  377.  
  378. 			Console.Error.WriteLine( );
  379.  
  380. 			Console.Error.Write( "Example:  " );
  381. 			Console.ForegroundColor = ConsoleColor.White;
  382. 			Console.Error.WriteLine( "LOCASE D:\\folder\\MYFILE.TXT /S:1" );
  383. 			Console.ResetColor( );
  384.  
  385. 			Console.Error.Write( "          will rename \"D:\\folder\\MYFILE.TXT\" to \"D:\\folder\\M" );
  386. 			Console.ForegroundColor = ConsoleColor.White;
  387. 			Console.Error.WriteLine( "yfile.txt\"" );
  388. 			Console.ResetColor( );
  389.  
  390. 			Console.Error.WriteLine( );
  391.  
  392. 			Console.Error.Write( "Example:  " );
  393. 			Console.ForegroundColor = ConsoleColor.White;
  394. 			Console.Error.WriteLine( "LOCASE D:\\folder\\MYFILE.TXT /S:0 /L:2" );
  395. 			Console.ResetColor( );
  396.  
  397. 			Console.Error.Write( "          will rename \"D:\\folder\\MYFILE.TXT\" to \"D:\\folder\\" );
  398. 			Console.ForegroundColor = ConsoleColor.White;
  399. 			Console.Error.Write( "my" );
  400. 			Console.ResetColor( );
  401. 			Console.Error.WriteLine( "FILE.TXT\"" );
  402.  
  403. 			Console.Error.WriteLine( );
  404.  
  405. 			Console.Error.WriteLine( "Written by Rob van der Woude" );
  406.  
  407. 			Console.Error.WriteLine( "https://www.robvanderwoude.com" );
  408.  
  409. 			#endregion Display Help Text
  410.  
  411. 			return -1;
  412. 		}
  413. 	}
  414. }

page last modified: 2024-04-16; loaded in 0.0280 seconds