粥里有勺糖

vuePress-theme-reco 粥里有勺糖    2018 - 2023
粥里有勺糖 粥里有勺糖

Choose mode

  • dark
  • auto
  • light
关于我
备战春秋
  • 心得总结
  • 校招考点汇总
  • 面经汇总
  • 复习自查
技术笔记
  • 技术教程
  • 模板工程
  • 源码学习
  • 技术概念
  • 个人作品
  • 学习笔记
计算机基础
  • 算法与数据结构
  • 操作系统
  • 计算机网络
  • 设计模式
  • 剑指offer
大前端
  • javascript
  • vue
  • html
  • css
  • 🌏浏览器专题
  • Web性能优化
  • regexp
  • node
面试
  • 问解
  • javascript
  • css
  • 手撕代码
  • 性能优化
  • 综合问题
  • 面经汇总
  • 小程序
手撕代码
  • 数据结构与算法
  • javascript
  • css
个人站点
  • GitHub (opens new window)
  • 博客园 (opens new window)
  • 掘金 (opens new window)
线上作品
  • 轻取(文件收集) (opens new window)
  • 个人图床 (opens new window)
  • 考勤小程序 (opens new window)
  • 时光恋人 (opens new window)
  • 在线简历生成 (opens new window)
留言板
Github (opens new window)
author-avatar

粥里有勺糖

285

文章

40

标签

关于我
备战春秋
  • 心得总结
  • 校招考点汇总
  • 面经汇总
  • 复习自查
技术笔记
  • 技术教程
  • 模板工程
  • 源码学习
  • 技术概念
  • 个人作品
  • 学习笔记
计算机基础
  • 算法与数据结构
  • 操作系统
  • 计算机网络
  • 设计模式
  • 剑指offer
大前端
  • javascript
  • vue
  • html
  • css
  • 🌏浏览器专题
  • Web性能优化
  • regexp
  • node
面试
  • 问解
  • javascript
  • css
  • 手撕代码
  • 性能优化
  • 综合问题
  • 面经汇总
  • 小程序
手撕代码
  • 数据结构与算法
  • javascript
  • css
个人站点
  • GitHub (opens new window)
  • 博客园 (opens new window)
  • 掘金 (opens new window)
线上作品
  • 轻取(文件收集) (opens new window)
  • 个人图床 (opens new window)
  • 考勤小程序 (opens new window)
  • 时光恋人 (opens new window)
  • 在线简历生成 (opens new window)
留言板
Github (opens new window)
  • devlearn

    • 开发教程
    • 实践:利用ArrayBuffer实现预览指定目录下的所有文件的内容
    • 在linux-deepin上使用deepin-wine5完美运行腾讯会议/QQ/微信等此类应用
    • eslint插件开发教程
    • ServerLess之云函数实践-天气API
    • 移动端阻止弹窗下层页面被滑动
    • 小技巧:for of中获取index
    • Git常用的一些基本操作
    • 向页面注入js实现为图片和文字元素添加透明蒙层
    • 实践:使用jsencrypt配合axios实现非对称加密传输的数据
    • 封装dotenv库实现类似Vite加载环境变量的行为
    • 30行代码实现合并指定目录下的所有文件的内容
    • 马上中秋了,把鼠标指针变为小玉兔
    • Node中require与fs.readFile读取JSON文件的对比
    • 使用免费的七牛云OSS(10G)搭建个人的在线图床
    • 分享封装的一些七牛云OSS操作方法
    • 本地配置SSH免密远程登录服务器
    • 工具方法汇总
    • 腾讯云Serverless实践-Node.js服务部署
    • 腾讯云Serverless实践-静态网站托管
    • 为什么'\x1B'.length === 1?\x与\u知识延伸
    • Vite插件开发纪实:vite-plugin-monitor(上)
    • Vite插件开发纪实:vite-plugin-monitor(中)
    • Vite插件开发纪实:vite-plugin-monitor(下)
    • 解决Vite-React项目中js使用jsx语法报错的问题
    • webpack 项目接入Vite的通用方案介绍
    • webpack 项目接入Vite的通用方案介绍-草稿
    • 优雅的处理挂载window上的函数可能不存在的情况
    • Mac上抓包秒通关羊了个羊

30行代码实现合并指定目录下的所有文件的内容

vuePress-theme-reco 粥里有勺糖    2018 - 2023

30行代码实现合并指定目录下的所有文件的内容

粥里有勺糖 2021-06-02 技术笔记技术教程

# 30行代码实现合并指定目录下的所有文件的内容

# 背景

临近毕业,肝完论文,指导老师叫把所有,所有,所有的源代码放附录

感到无语(它是不知道前端代码有好多),又无法拒绝

这么多文件,手动CV是不可能手动CV的,咱给它整个脚本,把内容合并到一个文件去,直接插入word

# 准备工作

装个Node环境即可

  • Node (opens new window)

# 目标

执行一行如下指令,就搞定目标目录的文件合并

node index.js <target_directory>
1

# 开工

# 获取指令传参

使用process模块,argv属性上表明了所有的参数

const process = require('process')

// 传入的目录
const targetDir = process.argv[2]

console.log(process.argv)
1
2
3
4
5
6

测试结果

node index.js /home/sugar/Documents/VueProject

# 打印结果
[
  '/home/sugar/.nvm/versions/node/v16.0.0/bin/node',
  '/home/sugar/Documents/VueProject/my-blog-vuepress/docs/technology/works/index.js',
  '/home/sugar/Documents/VueProject'
]
1
2
3
4
5
6
7
8

# 获取指定目录下的所有文件

思路

咱使用path,fs模块结合递归搞定:

  1. readdirSync方法获取所有的文件(包含目录)
  2. 通过isFile判断是否是文件
  3. 使用path.join拼接路径

具体实现如下

const path = require('path')
const fs = require('fs')
/**
 * 递归获取指定目录中的所有文件的绝对路径路径
 * @param {string} dir 目标目录
 * @param {string[]} 
 * @returns {string[]} 文件绝对路径数组
 */
function getDirFiles(dir) {
    let result = []
    let files = fs.readdirSync(dir, { withFileTypes: true })
    files.forEach(file => {
        const filepath = path.join(dir, file.name)
        if (file.isFile()) {
            result.push(filepath)
        } else if (file.isDirectory()) {
            result.push(...getDirFiles(filepath))
        }
    })
    return result;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

测试

console.log(getDirFiles('/home/sugar/Documents/VueProject/my-blog-vuepress/docs'));
1

打印结果,能获取到所有的文件的绝对路径

[
  '/home/sugar/Documents/VueProject/my-blog-vuepress/docs/.vuepress/comment.js',
  '/home/sugar/Documents/VueProject/my-blog-vuepress/docs/.vuepress/components/LeetCode.vue',
  ... 237 more items
]
1
2
3
4
5

结果中会出现.git,node_modules中的内容,咱加个过滤逻辑:

  • 使用数组存放,需要排出的目录或文件的相对路径
  • 使用endsWith方法进行匹配
  • Array.some方法遍历,符合条件则排除
/**
 * 递归获取指定目录中的所有文件的绝对路径路径
 * @param {string} dir 目标目录
 * @param {string[]} 
 * @returns {string[]} 文件绝对路径数组
 */
function getDirFiles(dir, exclude = []) {
    let result = []
    let files = fs.readdirSync(dir, { withFileTypes: true })
    files.forEach(file => {
        const filepath = path.join(dir, file.name)
        const isExclude = exclude.some(v => {
            return filepath.endsWith(v)
        })
        if (!isExclude) {
            if (file.isFile()) {
                result.push(filepath)
            } else if (file.isDirectory()) {
                result.push(...getDirFiles(filepath, exclude))
            }
        }
    })
    return result;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 合并文件目标文件的内容

思路:

  • 通过readFileSync读取指定文件的内容
  • 使用appendFileSync方法向目标文件追加内容
  • 使用Date.now生成时间戳,作为目标文件名

具体实现如下

/**
 * 内容并入一个文件中
 * @param {string[]} files 
 */
function mergeFile(files) {
    // 写入的目标文件(时间戳命名)
    const writeFilepath = path.join(__dirname, `${Date.now()}.txt`)
    files.forEach(f => {
        // 文件中的内容
        const txt = fs.readFileSync(f, { encoding: 'utf-8' })
        // 文件的相对路径(注意,这个targetDir是外部变量表示这些文件的公共目录,此行代码主要为获取文件的相对路径)
        const dir = f.slice(targetDir.length + 1)

        // 追加内容的方式
        fs.appendFileSync(writeFilepath, `${dir}\n`)
        fs.appendFileSync(writeFilepath, `${txt}\n\n`)
    })
    console.log('ok', files.length, '个文件');
    console.log(files);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 测试

以我当前的项目 (opens new window)为例子

node index.js /home/sugar/Documents/VueProject/my-blog-vuepress
1

结果

ok 309 个文件
1

图片

好家伙,敲了3w多行了

# 完整代码

const process = require('process')
const path = require('path')
const fs = require('fs')

// 传入的目录
const targetDir = process.argv[2]
// 忽略的内容
const ignore = ['node_modules', '.git', 'dist',
 'ignore', 'README.md', '.lock', '.png','docs','.eslintrc.js',
 '.env','LICENSE','tsconfig.json','.github','_tests_']

const files = getDirFiles(targetDir, ignore)

mergeFile(files)

/**
 * 内容并入一个文件中
 * @param {string[]} files 
 */
function mergeFile(files) {
    // 写入的目标文件(时间戳命名)
    const writeFilepath = path.join(__dirname, `${Date.now()}.txt`)
    files.forEach(f => {
        // 文件中的内容
        const txt = fs.readFileSync(f, { encoding: 'utf-8' })
        // 文件的相对路径
        const dir = f.slice(targetDir.length + 1)

        // 追加内容的方式
        fs.appendFileSync(writeFilepath, `${dir}\n`)
        fs.appendFileSync(writeFilepath, `${txt}\n\n`)
    })
    console.log('ok', files.length, '个文件');
    console.log(files);
}

/**
 * 递归获取指定目录中的所有文件的绝对路径路径
 * @param {string} dir 目标目录
 * @param {string[]} 
 * @returns {string[]} 文件绝对路径数组
 */
function getDirFiles(dir, exclude = []) {
    let result = []
    let files = fs.readdirSync(dir, { withFileTypes: true })
    files.forEach(file => {
        const filepath = path.join(dir, file.name)
        const isExclude = exclude.some(v => {
            return filepath.endsWith(v)
        })
        if (!isExclude) {
            if (file.isFile()) {
                result.push(filepath)
            } else if (file.isDirectory()) {
                result.push(...getDirFiles(filepath, exclude))
            }
        }
    })
    return result;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Edit this page (opens new window)
Last Updated: 2022/5/15 12:46:34