Line Filters in Swift

A line filter is a common type of program that reads input on stdin, processes it, and then prints some derived result to stdout. grep and sed are common line filters.

Here’s an example line filter in Swift that writes a capitalized version of all input text. You can use this pattern to write your own Swift line filters.

import Foundation

// Wrapping the unbuffered standard input with a buffered reader gives us a convenient
// readLine method that advances the reader to the next line.
let stdin = FileHandle.standardInput

// Process each line of input
while let line = readLine(strippingNewline: true) {
    // Convert the line to uppercase
    let uppercasedLine = line.uppercased()
    
    // Write out the uppercased line
    print(uppercasedLine)
}

// Check for errors during reading
// Note: In Swift, readLine() doesn't provide an error, it just returns nil at EOF
if let error = stdin.streamError {
    print("Error: \(error)", to: &StandardError())
    exit(1)
}

To try out our line filter, first make a file with a few lowercase lines.

$ echo 'hello'   > /tmp/lines
$ echo 'filter' >> /tmp/lines

Then use the line filter to get uppercase lines.

$ cat /tmp/lines | swift line-filters.swift
HELLO
FILTER

In this Swift version:

  1. We use FileHandle.standardInput to read from standard input.
  2. The readLine() function is used to read input line by line.
  3. We use a while loop with optional binding to process each line until we reach the end of the input.
  4. The uppercased() method is used to convert each line to uppercase.
  5. We use print() to write the uppercased line to standard output.
  6. Error handling is done by checking stdin.streamError after the loop. However, note that in Swift, readLine() doesn’t provide an error for end-of-file; it simply returns nil.
  7. We use StandardError() to print error messages to stderr.

This Swift code provides equivalent functionality to the original, reading input line by line, converting each line to uppercase, and writing the result to standard output.