如何使用Clojure读取文件并按规则拆分为多个带统一标识头的小文件
需求说明
- 源文件首行为标识符,必须放在所有生成的拆分文件开头
- 源文件后续每行为逗号分隔的数字对,循环均分到指定数量的拆分文件中
- 生成文件命名规则为
p1.dat、p2.dat……pn.dat
源文件示例:
12345 12000,2 13000,5 12501,1 ……拆分3份的结果示例:
p1.dat 内容:12345 12000,2 …… p2.dat 内容:12345 13000,5 …… p3.dat 内容:12345 12501,1 ……
Clojure 函数式实现
全程使用不可变数据操作,无命令式可变变量修改,完全符合函数式编程范式,功能和你提供的Ruby代码完全对齐:
#!/usr/bin/env bb (ns split-file (:require [clojure.string :as str] [clojure.java.io :as io])) ;; 入参校验 (when (< (count *command-line-args*) 1) (println "使用说明:传入待拆分文件路径,第二个可选参数为拆分份数,默认值为2") (System/exit 1)) (let [file-path (first *command-line-args*) n-parts (if (= (count *command-line-args*) 1) 2 (Integer/parseInt (second *command-line-args*))) ;; 读取文件全部内容 all-lines (str/split-lines (slurp file-path)) ;; 提取首行标识符 id-line (first all-lines) ;; 提取后续待分配的数据行 data-lines (rest all-lines) ;; 按索引取模完成循环分组,无可变状态 grouped-lines (group-by (fn [[idx _]] (mod idx n-parts)) (map-indexed vector data-lines))] ;; 遍历分组写入文件 (doseq [[group-idx lines-with-idx] grouped-lines :let [group-data (map second lines-with-idx) ;; 拼接每个文件的完整内容:标识符 + 对应分组数据行 file-content (str/join "\n" (concat [id-line] group-data)) file-name (str "p" (inc group-idx) ".dat")]] (spit file-name file-content) (println (str "文件 " file-name " 已生成"))))
使用说明
- 可以直接用Babashka(轻量级Clojure脚本运行环境)运行,和Ruby脚本使用体验一致,执行命令为:
bb split.clj 待拆分文件路径 [拆分份数] - 如果要打包成JVM运行的jar包,仅需调整入参读取逻辑为Clojure官方的
main函数入参即可。
内容的提问来源于stack exchange,提问作者skgifen
相关产品推荐
相关产品推荐

