Skip to content

Instantly share code, notes, and snippets.

@codejake
Last active March 7, 2025 19:31
Show Gist options
  • Select an option

  • Save codejake/df9fb6a5738e9cfaaa9f50f72d0a8b4c to your computer and use it in GitHub Desktop.

Select an option

Save codejake/df9fb6a5738e9cfaaa9f50f72d0a8b4c to your computer and use it in GitHub Desktop.
// This sucks. I'm probably doing it wrong. Please flame me.
import Foundation
enum FileSearchError: Error {
case fileNotFound
case readError(String)
}
/// Searches a file for lines containing a specific string and prints matching lines
/// - Parameters:
/// - searchString: The string to search for in each line
/// - filePath: The path to the file to search
/// - Throws: `FileSearchError` if the file cannot be opened or read
func searchFile(for searchString: String, in filePath: String) throws {
guard let fileHandle = FileHandle(forReadingAtPath: filePath) else {
throw FileSearchError.fileNotFound
}
defer {
if #available(macOS 15.0, *) {
try? fileHandle.close()
} else {
fileHandle.closeFile()
}
}
// I can use let here because the data isn't modified after assignment.
let fileData: Data
do {
// Get the file data
if #available(macOS 15.0, *) {
fileData = try fileHandle.readToEnd() ?? Data()
} else {
// Otherwise
fileData = fileHandle.readDataToEndOfFile()
}
// Convert to string
guard let fileContents = String(data: fileData, encoding: .utf8) else {
throw FileSearchError.readError("Could not decode file contents as UTF-8")
}
// Split into lines and search
let lines = fileContents.components(separatedBy: .newlines)
// Track if we found any matches
var matchFound = false
// Check each line for the search string
for (index, line) in lines.enumerated() {
if line.contains(searchString) {
print("Line \(index + 1): \(line)")
matchFound = true
}
}
if !matchFound {
print("No matches found for '\(searchString)' in \(filePath)")
}
} catch {
throw FileSearchError.readError(error.localizedDescription)
}
}
// Use like so:
// do {
// try searchFile(for: "Apple", in: "/Users/jake/.config/oui/manuf")
// } catch FileSearchError.fileNotFound {
// print("Error: The specified file could not be found.")
// } catch FileSearchError.readError(let errorMessage) {
// print("Error reading file: \(errorMessage)")
// } catch {
// print("An unexpected error occurred: \(error)")
// }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment