Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for dedup.cs

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Runtime.InteropServices;
  5. using System.Text.RegularExpressions;
  6.  
  7.  
  8. namespace RobvanderWoude
  9. {
  10. 	class DeDup
  11. 	{
  12. 		static string progver = "1.01";
  13.  
  14.  
  15. 		static int Main( string[] args )
  16. 		{
  17. 			#region Initialize Variables
  18.  
  19. 			bool ignorecase = false;
  20. 			bool ignorewhitespace = false;
  21. 			bool isredirected = ConsoleEx.InputRedirected;
  22. 			bool sortoutput = false;
  23. 			bool trimoutput = false;
  24. 			int redirectnum = ( isredirected ? 1 : 0 );
  25. 			int arguments = args.Length + redirectnum;
  26. 			string filename = string.Empty;
  27. 			string input = String.Empty;
  28.  
  29. 			#endregion Initialize Variables
  30.  
  31.  
  32. 			#region Command Line Parsing
  33.  
  34. 			if ( arguments == 0 )
  35. 			{
  36. 				return ShowHelp( );
  37. 			}
  38. 			if ( arguments > 1 )
  39. 			{
  40. 				for ( int i = 1 - redirectnum; i < args.Length; i++ )
  41. 				{
  42. 					if ( args[i][0] != '/' || args[i].Length < 2 )
  43. 					{
  44. 						return ShowHelp( "Invalid command line argument \"{0}\"", args[i] );
  45. 					}
  46. 					switch ( args[i][1].ToString( ).ToUpper( ) )
  47. 					{
  48. 						case "C":
  49. 							if ( ignorecase )
  50. 							{
  51. 								return ShowHelp( "Duplicate command line switch /C" );
  52. 							}
  53. 							ignorecase = true;
  54. 							break;
  55. 						case "S":
  56. 							if ( sortoutput )
  57. 							{
  58. 								return ShowHelp( "Duplicate command line switch /S" );
  59. 							}
  60. 							sortoutput = true;
  61. 							break;
  62. 						case "T":
  63. 							if ( trimoutput )
  64. 							{
  65. 								return ShowHelp( "Duplicate command line switch /T" );
  66. 							}
  67. 							trimoutput = true;
  68. 							break;
  69. 						case "W":
  70. 							if ( ignorewhitespace )
  71. 							{
  72. 								return ShowHelp( "Duplicate command line switch /W" );
  73. 							}
  74. 							ignorewhitespace = true;
  75. 							break;
  76. 						default:
  77. 							return ShowHelp( "Invalid command line switch {0}", args[i] );
  78. 					}
  79. 				}
  80. 			}
  81. 			if ( isredirected )
  82. 			{
  83. 				// Read the redirected Standard Input
  84. 				input = Console.In.ReadToEnd( );
  85. 			}
  86. 			else
  87. 			{
  88. 				filename = args[0];
  89. 				// Check if the file name is valid
  90. 				if ( filename.IndexOf( "/" ) > -1 )
  91. 				{
  92. 					return ShowHelp( );
  93. 				}
  94.  
  95. 				if ( filename.IndexOfAny( "?*".ToCharArray( ) ) > -1 )
  96. 				{
  97. 					return ShowHelp( "Wildcards not allowed" );
  98. 				}
  99.  
  100. 				// Check if the file exists
  101. 				if ( File.Exists( filename ) )
  102. 				{
  103. 					// Read the file content
  104. 					using ( StreamReader file = new StreamReader( filename ) )
  105. 					{
  106. 						input = file.ReadToEnd( );
  107. 					}
  108. 				}
  109. 				else
  110. 				{
  111. 					return ShowHelp( "File not found: \"" + filename + "\"" );
  112. 				}
  113. 			}
  114.  
  115. 			#endregion Command Line Parsing
  116.  
  117.  
  118. 			#region Check Each Line
  119.  
  120. 			List<string> deduplines = new List<string>( );
  121. 			Regex regex = new Regex( @"[\t ]+" );
  122. 			foreach ( string line in input.Split( "\n\r".ToCharArray( ) ) )
  123. 			{
  124. 				string checkline = line;
  125. 				if ( ignorewhitespace )
  126. 				{
  127. 					checkline = regex.Replace( checkline, " " );
  128. 				}
  129. 				if ( trimoutput )
  130. 				{
  131. 					checkline = checkline.Trim( );
  132. 				}
  133. 				if ( ignorecase )
  134. 				{
  135. 					bool found = false;
  136. 					foreach ( string storedline in deduplines )
  137. 					{
  138. 						if ( storedline.ToLower( ) == checkline.ToLower( ) )
  139. 						{
  140. 							found = true;
  141. 						}
  142. 					}
  143. 					if ( !found )
  144. 					{
  145. 						deduplines.Add( checkline );
  146. 					}
  147. 				}
  148. 				else
  149. 				{
  150. 					if ( !deduplines.Contains( checkline ) )
  151. 					{
  152. 						deduplines.Add( checkline );
  153. 					}
  154. 				}
  155. 			}
  156.  
  157. 			#endregion Check Each Line
  158.  
  159.  
  160. 			#region Display Results
  161.  
  162. 			if ( sortoutput )
  163. 			{
  164. 				deduplines.Sort( );
  165. 			}
  166.  
  167. 			foreach ( string line in deduplines )
  168. 			{
  169. 				Console.WriteLine( line );
  170. 			}
  171.  
  172. 			#endregion Display Results
  173.  
  174.  
  175. 			return 0;
  176. 		}
  177.  
  178.  
  179. 		// Displays help text
  180. 		static int ShowHelp( params string[] errmsg )
  181. 		{
  182. 			#region Help Text
  183.  
  184. 			/*
  185. 			DeDup.exe,  Version 1.00
  186. 			Remove duplicate lines from a text file or from redirected input
  187.  
  188. 			Usage:   DeDup.exe  "filename"  [ options ]
  189. 			   or:   some_command  |  DeDup.exe  [ options ]
  190.  
  191. 			Where:   "filename"    is the file to be investigated
  192. 			         some_command  is a command whose Standard Output is to be investigated
  193.  
  194. 			Options: /C            ignore Case
  195. 			         /S            Sort results
  196. 			         /T            Trim leading and trailing whitespace from output
  197. 			         /W            ignore Whitespace (any combination of tabs and/or
  198. 			                       spaces will be replaced by a single space in output)
  199.  
  200. 			Notes:   The filtered output is sent to the screen (Standard Output).
  201. 			         In case of duplicate lines, only the first match is returned.
  202.  
  203. 			Written by Rob van der Woude
  204. 			http://www.robvanderwoude.com
  205. 			*/
  206.  
  207. 			if ( errmsg.Length > 0 )
  208. 			{
  209. 				List<string> errargs = new List<string>( errmsg );
  210. 				errargs.RemoveAt( 0 );
  211. 				Console.Error.WriteLine( );
  212. 				Console.ForegroundColor = ConsoleColor.Red;
  213. 				Console.Error.Write( "ERROR:\t" );
  214. 				Console.ForegroundColor = ConsoleColor.White;
  215. 				Console.Error.WriteLine( errmsg[0], errargs.ToArray( ) );
  216. 				Console.ResetColor( );
  217. 			}
  218.  
  219. 			Console.Error.WriteLine( );
  220.  
  221. 			Console.Error.WriteLine( );
  222.  
  223. 			Console.Error.WriteLine( "DeDup,  Version {0}", progver );
  224.  
  225. 			Console.Error.WriteLine( "Remove duplicate lines from a text file or from redirected input" );
  226.  
  227. 			Console.Error.WriteLine( );
  228.  
  229. 			Console.Error.Write( "Usage:   " );
  230. 			Console.ForegroundColor = ConsoleColor.White;
  231. 			Console.Error.WriteLine( "DeDup.exe  \"filename\"  [ options ]" );
  232. 			Console.ResetColor( );
  233.  
  234. 			Console.Error.Write( "   or:   some_command  " );
  235. 			Console.ForegroundColor = ConsoleColor.White;
  236. 			Console.Error.WriteLine( "|  DeDup.exe  [ options ]" );
  237. 			Console.ResetColor( );
  238.  
  239. 			Console.Error.WriteLine( );
  240.  
  241. 			Console.Error.Write( "Where:   " );
  242. 			Console.ForegroundColor = ConsoleColor.White;
  243. 			Console.Error.Write( "\"filename\"" );
  244. 			Console.ResetColor( );
  245. 			Console.Error.WriteLine( "    is the file to be investigated" );
  246.  
  247. 			Console.ForegroundColor = ConsoleColor.White;
  248. 			Console.Error.Write( "         some_command" );
  249. 			Console.ResetColor( );
  250. 			Console.Error.WriteLine( "  is a command whose Standard Output is to be investigated" );
  251.  
  252. 			Console.Error.WriteLine( );
  253.  
  254. 			Console.Error.Write( "Options: " );
  255. 			Console.ForegroundColor = ConsoleColor.White;
  256. 			Console.Error.Write( "/C" );
  257. 			Console.ResetColor( );
  258. 			Console.Error.Write( "            ignore " );
  259. 			Console.ForegroundColor = ConsoleColor.White;
  260. 			Console.Error.Write( "C" );
  261. 			Console.ResetColor( );
  262. 			Console.Error.WriteLine( "ase" );
  263.  
  264. 			Console.ForegroundColor = ConsoleColor.White;
  265. 			Console.Error.Write( "         /S            S" );
  266. 			Console.ResetColor( );
  267. 			Console.Error.WriteLine( "ort results" );
  268.  
  269. 			Console.ForegroundColor = ConsoleColor.White;
  270. 			Console.Error.Write( "         /T            T" );
  271. 			Console.ResetColor( );
  272. 			Console.ResetColor( );
  273. 			Console.Error.WriteLine( "rim leading and trailing whitespace from output" );
  274.  
  275. 			Console.ForegroundColor = ConsoleColor.White;
  276. 			Console.Error.Write( "         /W" );
  277. 			Console.ResetColor( );
  278. 			Console.Error.Write( "            ignore " );
  279. 			Console.ForegroundColor = ConsoleColor.White;
  280. 			Console.Error.Write( "W" );
  281. 			Console.ResetColor( );
  282. 			Console.Error.WriteLine( "hitespace (any combination of tabs and/or" );
  283.  
  284. 			Console.Error.WriteLine( "                       spaces will be replaced by a single space in output)" );
  285.  
  286. 			Console.Error.WriteLine( );
  287.  
  288. 			Console.Error.WriteLine( "Notes:   The filtered output is sent to the screen (Standard Output)." );
  289.  
  290. 			Console.Error.WriteLine( "         In case of duplicate lines, only the first match is returned." );
  291.  
  292. 			Console.Error.WriteLine( );
  293.  
  294. 			Console.Error.WriteLine( "Written by Rob van der Woude" );
  295.  
  296. 			Console.Error.WriteLine( "http://www.robvanderwoude.com" );
  297.  
  298. 			#endregion Help Text
  299.  
  300. 			return 1;
  301. 		}
  302.  
  303.  
  304. 		#region Redirection Detection
  305.  
  306. 		// Code to detect redirection by Hans Passant on StackOverflow.com
  307. 		// http://stackoverflow.com/questions/3453220/how-to-detect-if-console-in-stdin-has-been-redirected
  308. 		public static class ConsoleEx
  309. 		{
  310. 			public static bool OutputRedirected
  311. 			{
  312. 				get
  313. 				{
  314. 					return FileType.Char != GetFileType( GetStdHandle( StdHandle.Stdout ) );
  315. 				}
  316. 			}
  317.  
  318. 			public static bool InputRedirected
  319. 			{
  320. 				get
  321. 				{
  322. 					return FileType.Char != GetFileType( GetStdHandle( StdHandle.Stdin ) );
  323. 				}
  324. 			}
  325.  
  326. 			public static bool ErrorRedirected
  327. 			{
  328. 				get
  329. 				{
  330. 					return FileType.Char != GetFileType( GetStdHandle( StdHandle.Stderr ) );
  331. 				}
  332. 			}
  333.  
  334. 			// P/Invoke:
  335. 			private enum FileType { Unknown, Disk, Char, Pipe };
  336. 			private enum StdHandle { Stdin = -10, Stdout = -11, Stderr = -12 };
  337.  
  338. 			[DllImport( "kernel32.dll" )]
  339. 			private static extern FileType GetFileType( IntPtr hdl );
  340.  
  341. 			[DllImport( "kernel32.dll" )]
  342. 			private static extern IntPtr GetStdHandle( StdHandle std );
  343. 		}
  344.  
  345. 		#endregion Redirection Detection
  346. 	}
  347. }
  348.  

page last uploaded: 2017-08-21, 14:26