[C#] C#从文件或者标准输入设备读取指定的行 →→→→→进入此内容的聊天室

来自 , 2021-03-30, 写在 C#, 查看 160 次.
URL http://www.code666.cn/view/f1b035b7
  1. using System;
  2. using System.IO;
  3. using System.Runtime.InteropServices;
  4. using System.Text.RegularExpressions;
  5. using System.Collections.Generic;
  6.  
  7. namespace RobvanderWoude
  8. {
  9.         class ReadLine
  10.         {
  11.                 static int Main( string[] args )
  12.                 {
  13.                         #region Command Line Parsing
  14.  
  15.                         string filename = string.Empty;
  16.                         int linestart = 1;
  17.                         int lineend = 2;
  18.                         bool concat = false;
  19.                         bool addspaces = false;
  20.                         string concatchar = string.Empty;
  21.                         bool skipempty = false;
  22.                         bool trimlines = false;
  23.                         bool numlines = false;
  24.                         bool redirected;
  25.                         bool set_c = false;
  26.                         bool set_l = false;
  27.                         bool set_s = false;
  28.                         bool set_t = false;
  29.                         bool set_input = false;
  30.  
  31.                         if ( ConsoleEx.InputRedirected )
  32.                         {
  33.                                 set_input = true;
  34.                                 redirected = true;
  35.                         }
  36.                         else
  37.                         {
  38.                                 if ( args.Length == 0 )
  39.                                 {
  40.                                         return WriteError( );
  41.                                 }
  42.                                 redirected = false;
  43.                         }
  44.  
  45.                         foreach ( string arg in args )
  46.                         {
  47.                                 if ( arg[0] == '/' )
  48.                                 {
  49.                                         try
  50.                                         {
  51.                                                 switch ( arg.ToUpper( )[1] )
  52.                                                 {
  53.                                                         case '?':
  54.                                                                 return WriteError( );
  55.                                                         case 'C':
  56.                                                                 if ( arg.ToUpper( ) != "/C" && arg.ToUpper( ) != "/CS" )
  57.                                                                 {
  58.                                                                         return WriteError( "Invalid command line switch " + arg );
  59.                                                                 }
  60.                                                                 concat = true;
  61.                                                                 if ( arg.ToUpper( ) == "/CS" )
  62.                                                                 {
  63.                                                                         addspaces = true;
  64.                                                                 }
  65.                                                                 if ( set_c )
  66.                                                                 {
  67.                                                                         return WriteError( "Duplicate command line argument /C*" );
  68.                                                                 }
  69.                                                                 set_c = true;
  70.                                                                 break;
  71.                                                         case 'L':
  72.                                                                 if ( arg.ToUpper( ).StartsWith( "/L:" ) && arg.Length > 3 )
  73.                                                                 {
  74.                                                                         if ( arg[2] == ':' )
  75.                                                                         {
  76.                                                                                 string linessel = arg.Substring( 3 );
  77.                                                                                 string pattern = @"^(\-?\d+)$";
  78.                                                                                 Match match = Regex.Match( linessel, pattern );
  79.                                                                                 if ( match.Success )
  80.                                                                                 {
  81.                                                                                         linestart = Convert.ToInt32( match.Groups[1].Value );
  82.                                                                                         lineend = linestart + 1;
  83.                                                                                 }
  84.                                                                                 else
  85.                                                                                 {
  86.                                                                                         pattern = @"^(\-?\d+)\.\.(\-?\d+)$";
  87.                                                                                         match = Regex.Match( linessel, pattern );
  88.                                                                                         if ( match.Success )
  89.                                                                                         {
  90.                                                                                                 linestart = Convert.ToInt32( match.Groups[1].Value );
  91.                                                                                                 lineend = Convert.ToInt32( match.Groups[2].Value ) + 1;
  92.                                                                                         }
  93.                                                                                         else
  94.                                                                                         {
  95.                                                                                                 pattern = @"^(\-?\d+),(\-?\d+)$";
  96.                                                                                                 match = Regex.Match( linessel, pattern );
  97.                                                                                                 if ( match.Success )
  98.                                                                                                 {
  99.                                                                                                         // numlines is true if the second number specifies the number of lines instead of a line number
  100.                                                                                                         numlines = true;
  101.                                                                                                         linestart = Convert.ToInt32( match.Groups[1].Value );
  102.                                                                                                         lineend = Convert.ToInt32( match.Groups[2].Value );
  103.                                                                                                         if ( lineend < 1 )
  104.                                                                                                         {
  105.                                                                                                                 return WriteError( "Invalid number of lines (" + lineend.ToString( ) + "), must be 1 or higher" );
  106.                                                                                                         }
  107.                                                                                                 }
  108.                                                                                         }
  109.                                                                                 }
  110.                                                                         }
  111.                                                                         else
  112.                                                                         {
  113.                                                                                 return WriteError( "Invalid command line switch " + arg );
  114.                                                                         }
  115.                                                                 }
  116.                                                                 else
  117.                                                                 {
  118.                                                                         return WriteError( "Invalid command line switch " + arg );
  119.                                                                 }
  120.                                                                 if ( set_l )
  121.                                                                 {
  122.                                                                         return WriteError( "Duplicate command line argument /L" );
  123.                                                                 }
  124.                                                                 set_l = true;
  125.                                                                 break;
  126.                                                         case 'S':
  127.                                                                 if ( arg.ToUpper( ) != "/SE" )
  128.                                                                 {
  129.                                                                         return WriteError( "Invalid command line switch " + arg );
  130.                                                                 }
  131.                                                                 skipempty = true;
  132.                                                                 if ( set_s )
  133.                                                                 {
  134.                                                                         return WriteError( "Duplicate command line argument /SE" );
  135.                                                                 }
  136.                                                                 set_s = true;
  137.                                                                 break;
  138.                                                         case 'T':
  139.                                                                 if ( arg.ToUpper( ) != "/T" )
  140.                                                                 {
  141.                                                                         return WriteError( "Invalid command line switch " + arg );
  142.                                                                 }
  143.                                                                 trimlines = true;
  144.                                                                 if ( set_t )
  145.                                                                 {
  146.                                                                         return WriteError( "Duplicate command line argument /T" );
  147.                                                                 }
  148.                                                                 set_t = true;
  149.                                                                 break;
  150.                                                         default:
  151.                                                                 return WriteError( "Invalid command line switch " + arg );
  152.                                                 }
  153.                                         }
  154.                                         catch
  155.                                         {
  156.                                                 return WriteError( "Invalid command line switch " + arg );
  157.                                         }
  158.                                 }
  159.                                 else
  160.                                 {
  161.                                         if ( set_input )
  162.                                         {
  163.                                                 return WriteError( "Multiple inputs specified (file + redirection or multiple files)" );
  164.                                         }
  165.                                         if ( redirected )
  166.                                         {
  167.                                                 return WriteError( "Do not specify a file name when using redirected input" );
  168.                                         }
  169.                                         else
  170.                                         {
  171.                                                 filename = arg;
  172.                                         }
  173.                                 }
  174.                         }
  175.  
  176.                         #endregion
  177.  
  178.                         try
  179.                         {
  180.                                 int count = 0;
  181.                                 bool output = false;
  182.                                 string[] lines;
  183.                                 List<string> alllines = new List<string>( );
  184.  
  185.                                 if ( redirected )
  186.                                 {
  187.                                         // Read standard input and store the lines in a list
  188.                                         int peek = 0;
  189.                                         do
  190.                                         {
  191.                                                 alllines.Add( Console.In.ReadLine( ) );
  192.                                         } while ( peek != -1 );
  193.                                         // Convert the list to an array
  194.                                         lines = alllines.ToArray( );
  195.                                 }
  196.                                 else
  197.                                 {
  198.                                         // Read the file and store the lines in a list
  199.                                         lines = File.ReadAllLines( filename );
  200.                                 }
  201.  
  202.                                 // Check if negative numbers were used, and if so, calculate the resulting line numbers
  203.                                 if ( linestart < 0 )
  204.                                 {
  205.                                         linestart += lines.Length + 1;
  206.                                 }
  207.                                 if ( lineend < 0 )
  208.                                 {
  209.                                         lineend += lines.Length + 1;
  210.                                 }
  211.                                 if ( numlines )
  212.                                 {
  213.                                         lineend += linestart;
  214.                                 }
  215.                                
  216.                                 // Iterate through the array of lines and display the ones matching the command line switches
  217.                                 foreach ( string line in lines )
  218.                                 {
  219.                                         string myline = line;
  220.                                         if ( trimlines )
  221.                                         {
  222.                                                 myline = myline.Trim( );
  223.                                         }
  224.                                         bool skip = skipempty && ( myline.Trim( ) == string.Empty );
  225.                                         if ( !skip )
  226.                                         {
  227.                                                 count += 1;
  228.                                                 if ( count >= linestart && count < lineend )
  229.                                                 {
  230.                                                         if ( concat )
  231.                                                         {
  232.                                                                 Console.Write( "{0}{1}", concatchar, myline );
  233.                                                         }
  234.                                                         else
  235.                                                         {
  236.                                                                 Console.WriteLine( myline );
  237.                                                         }
  238.                                                         if ( addspaces )
  239.                                                         {
  240.                                                                 concatchar = " ";
  241.                                                         }
  242.                                                 }
  243.                                         }
  244.                                 }
  245.                         }
  246.                         catch ( Exception e )
  247.                         {
  248.                                 return WriteError( e.Message );
  249.                         }
  250.  
  251.                         return 0;
  252.                 }
  253.  
  254.                 #region Redirection Detection
  255.  
  256.                 // Code to detect redirection by Hans Passant on StackOverflow.com
  257.                 // http://stackoverflow.com/questions/3453220/how-to-detect-if-console-in-stdin-has-been-redirected
  258.                 public static class ConsoleEx
  259.                 {
  260.                         public static bool OutputRedirected
  261.                         {
  262.                                 get
  263.                                 {
  264.                                         return FileType.Char != GetFileType( GetStdHandle( StdHandle.Stdout ) );
  265.                                 }
  266.                         }
  267.  
  268.                         public static bool InputRedirected
  269.                         {
  270.                                 get
  271.                                 {
  272.                                         return FileType.Char != GetFileType( GetStdHandle( StdHandle.Stdin ) );
  273.                                 }
  274.                         }
  275.  
  276.                         public static bool ErrorRedirected
  277.                         {
  278.                                 get
  279.                                 {
  280.                                         return FileType.Char != GetFileType( GetStdHandle( StdHandle.Stderr ) );
  281.                                 }
  282.                         }
  283.  
  284.                         // P/Invoke:
  285.                         private enum FileType { Unknown, Disk, Char, Pipe };
  286.                         private enum StdHandle { Stdin = -10, Stdout = -11, Stderr = -12 };
  287.  
  288.                         [DllImport( "kernel32.dll" )]
  289.                         private static extern FileType GetFileType( IntPtr hdl );
  290.  
  291.                         [DllImport( "kernel32.dll" )]
  292.                         private static extern IntPtr GetStdHandle( StdHandle std );
  293.                 }
  294.  
  295.                 #endregion
  296.  
  297.                 #region Error Handling
  298.  
  299.                 public static int WriteError( Exception e = null )
  300.                 {
  301.                         return WriteError( e == null ? null : e.Message );
  302.                 }
  303.  
  304.                 public static int WriteError( string errorMessage )
  305.                 {
  306.                         if ( string.IsNullOrEmpty( errorMessage ) == false )
  307.                         {
  308.                                 Console.Error.WriteLine( );
  309.                                 Console.ForegroundColor = ConsoleColor.Red;
  310.                                 Console.Error.Write( "ERROR: " );
  311.                                 Console.ForegroundColor = ConsoleColor.White;
  312.                                 Console.Error.WriteLine( errorMessage );
  313.                                 Console.ResetColor( );
  314.                         }
  315.  
  316.                         /*
  317.                         ReadLine,  Version 0.30 beta
  318.                         Return the specified line(s) from a file or Standard Input
  319.  
  320.                         Usage:   READLINE  filename  [ options ]
  321.                            or:   READLINE  [ options ]  <  filename
  322.                            or:   command  |  READLINE  [ options ]
  323.  
  324.                         Where:   filename   is the optional file to be read
  325.                                          command    is the optional command whose output is to be read
  326.  
  327.                         Options: /C         Concatenate lines
  328.                                          /CS        Concatenate lines with Spaces in between
  329.                                          /L:n       read line n
  330.                                          /L:n..m    read lines n through m
  331.                                          /L:n,m     read m lines starting at line n
  332.                                                                 (negative numbers start counting from the end backwards)
  333.                                          /SE        Skip Empty lines
  334.                                  /T         Trim leading and trailing whitespace from lines
  335.  
  336.                         Examples:
  337.                         READLINE  file                        read the first non-empty line (default)
  338.                         READLINE  file  /L:2  /SE             read the second non-empty line of file
  339.                         READLINE  file  /L:5..7               read lines 5..7 of file
  340.                         READLINE  file  /L:-1                 read the last line of file
  341.                         READLINE  file  /L:-2..-1             read the last 2 lines of file
  342.                         READLINE  file  /L:-2,2               read the last 2 lines of file
  343.  
  344.                         Check for redirection by Hans Passant on StackOverflow.com
  345.                         /questions/3453220/how-to-detect-if-console-in-stdin-has-been-redirected
  346.  
  347.                         Written by Rob van der Woude
  348.                         http://www.robvanderwoude.com
  349.                         */
  350.  
  351.                         Console.Error.WriteLine( );
  352.                         Console.Error.WriteLine( "ReadLine,  Version 0.30 beta" );
  353.                         Console.Error.WriteLine( "Return the specified line(s) from a file or Standard Input" );
  354.                         Console.Error.WriteLine( );
  355.                         Console.Error.Write( "Usage:   " );
  356.                         Console.ForegroundColor = ConsoleColor.White;
  357.                         Console.Error.WriteLine( "READLINE  filename  [ options ]" );
  358.                         Console.ResetColor( );
  359.                         Console.Error.Write( "   or:   " );
  360.                         Console.ForegroundColor = ConsoleColor.White;
  361.                         Console.Error.WriteLine( "READLINE  [ options ]  <  filename" );
  362.                         Console.ResetColor( );
  363.                         Console.Error.Write( "   or:   " );
  364.                         Console.ForegroundColor = ConsoleColor.White;
  365.                         Console.Error.WriteLine( "command  |  READLINE  [ options ]" );
  366.                         Console.ResetColor( );
  367.                         Console.Error.WriteLine( );
  368.                         Console.Error.Write( "Where:   " );
  369.                         Console.ForegroundColor = ConsoleColor.White;
  370.                         Console.Error.Write( "filename" );
  371.                         Console.ResetColor( );
  372.                         Console.Error.WriteLine( "   is the optional file to be read" );
  373.                         Console.ForegroundColor = ConsoleColor.White;
  374.                         Console.Error.Write( "         command" );
  375.                         Console.ResetColor( );
  376.                         Console.Error.WriteLine( "    is the optional command whose output is to be read" );
  377.                         Console.Error.WriteLine( );
  378.                         Console.Error.Write( "Options: " );
  379.                         Console.ForegroundColor = ConsoleColor.White;
  380.                         Console.Error.Write( "/C         C" );
  381.                         Console.ResetColor( );
  382.                         Console.Error.WriteLine( "oncatenate lines" );
  383.                         Console.ForegroundColor = ConsoleColor.White;
  384.                         Console.Error.Write( "         /CS        C" );
  385.                         Console.ResetColor( );
  386.                         Console.Error.Write( "oncatenate lines with " );
  387.                         Console.ForegroundColor = ConsoleColor.White;
  388.                         Console.Error.Write( "S" );
  389.                         Console.ResetColor( );
  390.                         Console.Error.WriteLine( "paces in between" );
  391.                         Console.ForegroundColor = ConsoleColor.White;
  392.                         Console.Error.Write( "         /L:n" );
  393.                         Console.ResetColor( );
  394.                         Console.Error.Write( "       read line " );
  395.                         Console.ForegroundColor = ConsoleColor.White;
  396.                         Console.Error.WriteLine( "n" );
  397.                         Console.ResetColor( );
  398.                         Console.ForegroundColor = ConsoleColor.White;
  399.                         Console.Error.Write( "         /L:n..m" );
  400.                         Console.ResetColor( );
  401.                         Console.Error.Write( "    read lines " );
  402.                         Console.ForegroundColor = ConsoleColor.White;
  403.                         Console.Error.Write( "n" );
  404.                         Console.ResetColor( );
  405.                         Console.Error.Write( " through " );
  406.                         Console.ForegroundColor = ConsoleColor.White;
  407.                         Console.Error.WriteLine( "m" );
  408.                         Console.Error.Write( "         /L:n,m" );
  409.                         Console.ResetColor( );
  410.                         Console.Error.Write( "     read " );
  411.                         Console.ForegroundColor = ConsoleColor.White;
  412.                         Console.Error.Write( "m" );
  413.                         Console.ResetColor( );
  414.                         Console.Error.Write( " lines starting at line " );
  415.                         Console.ForegroundColor = ConsoleColor.White;
  416.                         Console.Error.WriteLine( "n" );
  417.                         Console.ResetColor( );
  418.                         Console.Error.WriteLine( "                    (negative numbers start counting from the end backwards)" );
  419.                         Console.ForegroundColor = ConsoleColor.White;
  420.                         Console.Error.Write( "         /SE        S" );
  421.                         Console.ResetColor( );
  422.                         Console.Error.Write( "kip " );
  423.                         Console.ForegroundColor = ConsoleColor.White;
  424.                         Console.Error.Write( "E" );
  425.                         Console.ResetColor( );
  426.                         Console.Error.WriteLine( "mpty lines" );
  427.                         Console.ForegroundColor = ConsoleColor.White;
  428.                         Console.Error.Write( "         /T         T" );
  429.                         Console.ResetColor( );
  430.                         Console.Error.WriteLine( "rim leading and trailing whitespace from lines" );
  431.                         Console.Error.WriteLine( );
  432.                         Console.Error.WriteLine( "Examples:" );
  433.                         Console.Error.WriteLine( "READLINE  file                        read the first non-empty line (default)" );
  434.                         Console.Error.WriteLine( "READLINE  file  /L:2  /SE             read the second non-empty line of file" );
  435.                         Console.Error.WriteLine( "READLINE  file  /L:5..7               read lines 5..7 of file" );
  436.                         Console.Error.WriteLine( "READLINE  file  /L:-1                 read the last line of file" );
  437.                         Console.Error.WriteLine( "READLINE  file  /L:-2..-1             read the last 2 lines of file" );
  438.                         Console.Error.WriteLine( "READLINE  file  /L:-2,2               read the last 2 lines of file" );
  439.                         Console.Error.WriteLine( );
  440.                         Console.Error.Write( "Check for redirection by Hans Passant on " );
  441.                         Console.ForegroundColor = ConsoleColor.DarkGray;
  442.                         Console.Error.WriteLine( "StackOverflow.com" );
  443.                         Console.Error.WriteLine( "/questions/3453220/how-to-detect-if-console-in-stdin-has-been-redirected" );
  444.                         Console.ResetColor( );
  445.                         Console.Error.WriteLine( );
  446.                         Console.Error.WriteLine( "Written by Rob van der Woude" );
  447.                         Console.Error.WriteLine( "http://www.robvanderwoude.com" );
  448.                         return 1;
  449.                 }
  450.  
  451.                 #endregion
  452.  
  453.         }
  454. }
  455. //csharp/7348

回复 "C#从文件或者标准输入设备读取指定的行"

这儿你可以回复上面这条便签

captcha