You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Common Lisp+Quicklisp+cl-csv:如何读取CSV指定单行?

解决cl-csv读取指定单行的问题

咱先来搞懂你遇到的错误:你用(cl-csv:read-csv-row #P"file.csv" 5)报错,是因为read-csv-row这个函数的参数规则里,第二个及以后的参数必须是关键字参数(比如:separator #\,这种键值对),你直接传数字5作为位置参数,它会误以为这是关键字参数的一部分,自然就报出"keyword arguments should occur pairwise"的错误了。

那cl-csv支持读取指定单行吗?答案是:它没有直接提供一行到位的函数,但我们可以通过两种简单的方式实现这个需求:

方法一:逐行遍历到目标行

这种方法适合大文件,因为不需要读取整个CSV,到目标行就可以停止,效率更高:

(defun read-nth-csv-row (file-path target-row-num)
  (with-open-file (stream file-path)
    ;; 先跳过前target-row-num-1行
    (loop repeat (1- target-row-num)
          do (cl-csv:read-csv-row stream))
    ;; 读取并返回目标行
    (cl-csv:read-csv-row stream)))

调用示例:

(read-nth-csv-row #P"file.csv" 5) ; 获取第5行

方法二:用read-csv配合回调筛选

这种方法代码更简洁,适合小文件,通过read-csv的:row-fn回调函数,在读取每一行时检查行号,匹配到目标行就直接返回:

(defun read-nth-csv-row (file-path target-row-num)
  (let ((result nil))
    (cl-csv:read-csv file-path
                     :row-num t  ; 让回调函数能拿到行号参数
                     :row-fn (lambda (row row-number)
                               (when (= row-number target-row-num)
                                 (setf result row)
                                 ;; 找到目标行后直接跳出函数,不用继续读剩下的内容
                                 (return-from read-nth-csv-row result))))
    result))

调用示例和方法一一样,传入文件路径和目标行号即可。

注意点

  • 行号是从1开始计数的(如果你的CSV第一行是表头,那要根据自己的需求调整目标行号);
  • 如果目标行号超过了文件的总行数,两种方法都会返回nil,你可以根据需要添加错误处理逻辑。

内容的提问来源于stack exchange,提问作者pxlkllr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:24:24