How MS-DOS 6.22 FIND Searches Text Files

The MS-DOS 6.22 FIND utility is a primitive command-line stream filter designed to locate literal character patterns within plain text files or piped standard input. Operating within the constraints of 16-bit real-mode memory, it reads files sequentially, isolates lines of text using standard line-ending bytes, and applies direct, byte-by-byte substring comparisons to determine matches without the use of regular expressions.

Sequential File Ingestion and Buffering

When executed, FIND.EXE opens the specified target file using MS-DOS Interrupt 21h (Function 3Dh) and loads data into a fixed internal memory buffer via read operations (Function 3Fh). If multiple files are specified, it processes them strictly in order, one by one. The utility does not map the entire file into memory; instead, it processes continuous byte streams, tracking position and state incrementally to accommodate systems with minimal RAM.

Line Delimitation

MS-DOS text files represent new lines using a two-byte sequence: Carriage Return (CR, ASCII 0x0D) followed by Line Feed (LF, ASCII 0x0A). As FIND pulls data from its buffer, it scans continuously for these boundary markers. Each slice of data between CRLF sequences is treated as an individual record. This boundary detection allows the tool to maintain an internal line counter, which is utilized when the /N switch is provided to output line numbers.

Literal Substring Matching Algorithm

Unlike advanced search utilities like Unix grep, FIND does not compile patterns into deterministic finite automata (DFA) or handle regular expressions. It treats the search target strictly as an exact sequence of bytes.

The search engine employs a naive, sliding-window substring algorithm:

  1. It reads the current line character by character.
  2. It compares the current character with the first character of the target string.
  3. If a match occurs, it checks subsequent bytes against the remainder of the target string.
  4. If a mismatch occurs, the pointer resets to the next character in the line and resumes the comparison.

Case Sensitivity and Normalization

By default, FIND executes an exact ASCII match where A (ASCII 0x41) does not match a (ASCII 0x61). When the case-insensitive switch (/I) is passed, the utility normalizes the input stream and the search string during the comparison stage. It typically converts lowercase characters (ASCII 0x61–0x7A) to uppercase (ASCII 0x41–0x5A) in memory before comparing the byte values.

Output Processing Flags

Once a line scan concludes, FIND routes the data to standard output (STDOUT) based on command-line flags:

  • Default: Outputs the matching line if the string is detected.
  • /V (Invert): Reverses the boolean match logic, printing only lines where the target string was not found.
  • /C (Count): Suppresses the display of line contents and instead increments a match counter, printing only the final tally per file after EOF (End of File) is reached.
  • /N (Number): Prepends the buffered line with its sequential line index formatted in brackets (e.g., [12]).