5 分钟用 Swift 写个 ripripgrep

169 天前
 MrKrabs

你别管什么 NFC ,NFD ,咱只是想搜出日语呢

import Foundation
import ArgumentParser

@main
struct Ripripgrep: ParsableCommand {

  @Option(name: .shortAndLong)
  var patterns: [String]

  @Argument(help: "use stdin if no args")
  var files: [String] = []

  func validate() throws {
    if patterns.isEmpty {
      fatalError("no patterns!")
    }
  }

  struct Worker {
    var line: UnsafeMutablePointer<CChar>?
    var linecap = 0
    let patterns: [Regex<AnyRegexOutput>]

    mutating func start(stream: UnsafeMutablePointer<FILE>) {
      while case let linelen = getline(&line, &linecap, stream),
            linelen > 0 {
        let line = String(decoding: UnsafeRawBufferPointer(start: line!, count: linelen-1), as: UTF8.self)
        if patterns.allSatisfy({ line.contains($0) }) {
          print(line)
        }
      }
    }
  }

  func run() throws {

    var worker = Worker(patterns: try patterns.map { try Regex($0).ignoresCase() })

    if files.isEmpty {
      // use stdin
      worker.start(stream: stdin)
    } else {
      for file in files {
        let stream = fopen(file, "rb")!
        defer { fclose(stream) }
        worker.start(stream: stream)
      }
    }
  }

}

1568 次点击
所在节点    Swift
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1120436

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX