This commit is contained in:
pqcqaq 2025-01-15 20:20:21 +08:00
commit ebe81223d8
9 changed files with 809 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/node_modules
/in
/out

222
lib/index.js Normal file
View File

@ -0,0 +1,222 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const child_process_1 = require("child_process");
const adm_zip_1 = __importDefault(require("adm-zip"));
const DISALLOWED_EXTENSIONS = new Set([
".exe",
".o",
".class",
".bin",
".dll",
".vcxproj",
".filters",
".user",
".sln",
]);
const DISALLOWED_KEYWORDS = new Set(["a.out", "main", "temp"]);
const DISALLOWED_DIRECTORIES = new Set([
".vs",
".idea",
"__pycache__",
"node_modules",
".git",
"x64",
"x86",
"__MACOSX",
".vscode",
]);
let deletedItems = [];
// 清理文件名
const sanitizeFileName = (fileName) => {
// 对文件名进行标准化处理,解决编码问题
const decodedName = fileName.toString("utf8");
return decodedName;
};
// 检查是否是压缩文件
const isCompressedFile = (filePath) => {
return (filePath.endsWith(".zip") ||
filePath.endsWith(".7z") ||
filePath.endsWith(".rar"));
};
// 测试是否安装了7z和unrar
const preTest = () => {
try {
(0, child_process_1.execSync)("7z --help");
}
catch (e) {
console.error("[ERROR] 7z 未安装,请先安装 7z。");
process.exit(1);
}
try {
(0, child_process_1.execSync)("unrar");
}
catch (e) {
console.error("[ERROR] unrar 未安装,请先安装 unrar。");
process.exit(1);
}
};
// 检查文件是否可能是Linux可执行文件无后缀的二进制
const isLinuxExecutable = (filePath) => {
if (fs_1.default.statSync(filePath).isFile() && path_1.default.extname(filePath) === "") {
const stats = fs_1.default.statSync(filePath);
return (stats.mode & 0o111) !== 0;
}
return false;
};
// 使用7z解压文件
const extractUsing7z = (filePath, extractTo) => {
console.log(`[INFO] 使用 7z 解压文件: ${filePath} 到目录: ${extractTo}`);
if (!fs_1.default.existsSync(extractTo)) {
fs_1.default.mkdirSync(extractTo, { recursive: true });
}
try {
(0, child_process_1.execSync)(`7z x "${filePath}" -o"${extractTo}"`);
console.log(`[INFO] 解压完成: ${filePath}`);
}
catch (e) {
console.error(`[ERROR] 解压失败: ${e}`);
}
};
// 使用unrar解压文件
const extractRar = (filePath, extractTo) => {
console.log(`[INFO] 使用 unrar 解压文件: ${filePath} 到目录: ${extractTo}`);
if (!fs_1.default.existsSync(extractTo)) {
fs_1.default.mkdirSync(extractTo, { recursive: true });
}
try {
(0, child_process_1.execSync)(`unrar x -o+ "${filePath}" "${extractTo}"`);
console.log(`[INFO] 解压完成: ${filePath}`);
}
catch (e) {
console.error(`[ERROR] 解压失败: ${e}`);
}
};
/**
* 解压缩文件
* @param inputDirectory 输入目录
* @param outputDirectory 输出目录
* @deprecated 存在编码问题暂时不使用
*/
const extractZip = (filePath, extractTo) => {
console.log(`[INFO] 解压缩文件: ${filePath} 到目录: ${extractTo}`);
if (!fs_1.default.existsSync(extractTo)) {
fs_1.default.mkdirSync(extractTo, { recursive: true });
}
const zip = new adm_zip_1.default(filePath);
// 遍历所有的文件条目,清理文件名中的非法字符
zip.getEntries().forEach((entry) => {
if (entry.entryName) {
try {
// 清理文件名中的非法字符
const sanitizedName = sanitizeFileName(entry.rawEntryName);
entry.entryName = sanitizedName; // 更新文件名
}
catch (e) {
console.error(`[ERROR] 解压时处理文件名失败: ${entry.entryName}`);
}
}
});
// 解压文件
zip.extractAllTo(extractTo, true);
};
// 递归处理目录并过滤文件
const processDirectory = (inputDirectory, outputDirectory) => {
console.log(`[INFO] 开始处理目录: ${inputDirectory}`);
fs_1.default.readdirSync(inputDirectory).forEach((item) => {
const itemPath = path_1.default.join(inputDirectory, item);
const stat = fs_1.default.statSync(itemPath);
if (stat.isDirectory()) {
// 排除不需要的目录
if (DISALLOWED_DIRECTORIES.has(item)) {
deletedItems.push(`目录: ${itemPath}`);
fs_1.default.rmdirSync(itemPath, { recursive: true });
console.log(`[DELETE] 删除目录: ${itemPath}`);
}
else {
// 创建对应的输出目录
const outputDirPath = path_1.default.join(outputDirectory, item);
if (!fs_1.default.existsSync(outputDirPath)) {
fs_1.default.mkdirSync(outputDirPath, { recursive: true });
}
processDirectory(itemPath, outputDirPath); // 递归处理子目录
}
}
else if (stat.isFile()) {
const ext = path_1.default.extname(item).toLowerCase();
// 如果是压缩文件,解压后递归处理
if (isCompressedFile(itemPath)) {
const relativePath = path_1.default.relative(inputDirectory, path_1.default.dirname(itemPath));
const outputDirPath = path_1.default.join(outputDirectory, relativePath, path_1.default.basename(itemPath, path_1.default.extname(itemPath)) +
"_extracted");
if (!fs_1.default.existsSync(outputDirPath)) {
fs_1.default.mkdirSync(outputDirPath, { recursive: true });
}
if (itemPath.endsWith(".zip")) {
// extractZip(itemPath, outputDirPath); // 存在编码问题,暂时不使用
extractUsing7z(itemPath, outputDirPath);
}
else if (itemPath.endsWith(".7z")) {
extractUsing7z(itemPath, outputDirPath);
}
else if (itemPath.endsWith(".rar")) {
extractRar(itemPath, outputDirPath);
}
// 递归处理解压后的内容
processDirectory(outputDirPath, outputDirPath);
// 重新压缩处理后的内容
const outputZip = path_1.default.join(outputDirectory, relativePath, path_1.default.basename(itemPath));
const zip = new adm_zip_1.default();
zip.addLocalFolder(outputDirPath);
zip.writeZip(outputZip);
// 删除临时目录
console.log(`[DELETE] 删除临时目录: ${outputDirPath}`);
fs_1.default.rmSync(outputDirPath, { recursive: true, force: true });
}
else if (DISALLOWED_EXTENSIONS.has(ext) ||
DISALLOWED_KEYWORDS.has(item) ||
isLinuxExecutable(itemPath)) {
console.log(`[DELETE] 删除文件: ${itemPath}`);
deletedItems.push(`文件: ${itemPath}`);
fs_1.default.rmSync(itemPath); // 删除不需要的文件
}
else {
// 将文件复制到对应的输出目录
const outputFilePath = path_1.default.join(outputDirectory, item);
fs_1.default.copyFileSync(itemPath, outputFilePath);
console.log(`[KEEP] 保留文件: ${itemPath} 并复制到 ${outputFilePath}`);
}
}
});
};
// 写入统计文件
const writeLog = (outputDirectory) => {
const logFile = path_1.default.join(outputDirectory, "result_log.txt");
fs_1.default.writeFileSync(logFile, "以下是被删除的目录和文件列表:\n");
fs_1.default.appendFileSync(logFile, deletedItems.join("\n"));
console.log(`[INFO] 统计文件已生成: ${logFile}`);
};
// 主函数
const main = () => {
preTest(); // 测试是否安装了7z和unrar
const inputDirectory = path_1.default.join(process.cwd(), "in"); // 输入文件夹
const outputDirectory = path_1.default.join(process.cwd(), "out"); // 输出文件夹
if (!fs_1.default.existsSync(inputDirectory)) {
console.error(`[ERROR] 输入目录 'in' 不存在,请检查。`);
return;
}
if (fs_1.default.existsSync(outputDirectory)) {
fs_1.default.rmSync(outputDirectory, { recursive: true }); // 清空输出目录
}
fs_1.default.mkdirSync(outputDirectory, { recursive: true });
console.log("[INFO] 开始处理压缩文件...");
processDirectory(inputDirectory, outputDirectory);
writeLog(outputDirectory);
console.log('[INFO] 处理完成!结果保存在 "out" 目录中。');
};
main();
//# sourceMappingURL=index.js.map

1
lib/index.js.map Normal file

File diff suppressed because one or more lines are too long

222
lib/process_zip_files.js Normal file
View File

@ -0,0 +1,222 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const child_process_1 = require("child_process");
const adm_zip_1 = __importDefault(require("adm-zip"));
const DISALLOWED_EXTENSIONS = new Set([
".exe",
".o",
".class",
".bin",
".dll",
".vcxproj",
".filters",
".user",
".sln",
]);
const DISALLOWED_KEYWORDS = new Set(["a.out", "main", "temp"]);
const DISALLOWED_DIRECTORIES = new Set([
".vs",
".idea",
"__pycache__",
"node_modules",
".git",
"x64",
"x86",
"__MACOSX",
".vscode",
]);
let deletedItems = [];
// 清理文件名
const sanitizeFileName = (fileName) => {
// 对文件名进行标准化处理,解决编码问题
const decodedName = fileName.toString("utf8");
return decodedName;
};
// 检查是否是压缩文件
const isCompressedFile = (filePath) => {
return (filePath.endsWith(".zip") ||
filePath.endsWith(".7z") ||
filePath.endsWith(".rar"));
};
// 测试是否安装了7z和unrar
const preTest = () => {
try {
(0, child_process_1.execSync)("7z --help");
}
catch (e) {
console.error("[ERROR] 7z 未安装,请先安装 7z。");
process.exit(1);
}
try {
(0, child_process_1.execSync)("unrar");
}
catch (e) {
console.error("[ERROR] unrar 未安装,请先安装 unrar。");
process.exit(1);
}
};
// 检查文件是否可能是Linux可执行文件无后缀的二进制
const isLinuxExecutable = (filePath) => {
if (fs_1.default.statSync(filePath).isFile() && path_1.default.extname(filePath) === "") {
const stats = fs_1.default.statSync(filePath);
return (stats.mode & 0o111) !== 0;
}
return false;
};
// 使用7z解压文件
const extractUsing7z = (filePath, extractTo) => {
console.log(`[INFO] 使用 7z 解压文件: ${filePath} 到目录: ${extractTo}`);
if (!fs_1.default.existsSync(extractTo)) {
fs_1.default.mkdirSync(extractTo, { recursive: true });
}
try {
(0, child_process_1.execSync)(`7z x "${filePath}" -o"${extractTo}"`);
console.log(`[INFO] 解压完成: ${filePath}`);
}
catch (e) {
console.error(`[ERROR] 解压失败: ${e}`);
}
};
// 使用unrar解压文件
const extractRar = (filePath, extractTo) => {
console.log(`[INFO] 使用 unrar 解压文件: ${filePath} 到目录: ${extractTo}`);
if (!fs_1.default.existsSync(extractTo)) {
fs_1.default.mkdirSync(extractTo, { recursive: true });
}
try {
(0, child_process_1.execSync)(`unrar x -o+ "${filePath}" "${extractTo}"`);
console.log(`[INFO] 解压完成: ${filePath}`);
}
catch (e) {
console.error(`[ERROR] 解压失败: ${e}`);
}
};
/**
* 解压缩文件
* @param inputDirectory 输入目录
* @param outputDirectory 输出目录
* @deprecated 存在编码问题暂时不使用
*/
const extractZip = (filePath, extractTo) => {
console.log(`[INFO] 解压缩文件: ${filePath} 到目录: ${extractTo}`);
if (!fs_1.default.existsSync(extractTo)) {
fs_1.default.mkdirSync(extractTo, { recursive: true });
}
const zip = new adm_zip_1.default(filePath);
// 遍历所有的文件条目,清理文件名中的非法字符
zip.getEntries().forEach((entry) => {
if (entry.entryName) {
try {
// 清理文件名中的非法字符
const sanitizedName = sanitizeFileName(entry.rawEntryName);
entry.entryName = sanitizedName; // 更新文件名
}
catch (e) {
console.error(`[ERROR] 解压时处理文件名失败: ${entry.entryName}`);
}
}
});
// 解压文件
zip.extractAllTo(extractTo, true);
};
// 递归处理目录并过滤文件
const processDirectory = (inputDirectory, outputDirectory) => {
console.log(`[INFO] 开始处理目录: ${inputDirectory}`);
fs_1.default.readdirSync(inputDirectory).forEach((item) => {
const itemPath = path_1.default.join(inputDirectory, item);
const stat = fs_1.default.statSync(itemPath);
if (stat.isDirectory()) {
// 排除不需要的目录
if (DISALLOWED_DIRECTORIES.has(item)) {
deletedItems.push(`目录: ${itemPath}`);
fs_1.default.rmdirSync(itemPath, { recursive: true });
console.log(`[DELETE] 删除目录: ${itemPath}`);
}
else {
// 创建对应的输出目录
const outputDirPath = path_1.default.join(outputDirectory, item);
if (!fs_1.default.existsSync(outputDirPath)) {
fs_1.default.mkdirSync(outputDirPath, { recursive: true });
}
processDirectory(itemPath, outputDirPath); // 递归处理子目录
}
}
else if (stat.isFile()) {
const ext = path_1.default.extname(item).toLowerCase();
// 如果是压缩文件,解压后递归处理
if (isCompressedFile(itemPath)) {
const relativePath = path_1.default.relative(inputDirectory, path_1.default.dirname(itemPath));
const outputDirPath = path_1.default.join(outputDirectory, relativePath, path_1.default.basename(itemPath, path_1.default.extname(itemPath)) +
"_extracted");
if (!fs_1.default.existsSync(outputDirPath)) {
fs_1.default.mkdirSync(outputDirPath, { recursive: true });
}
if (itemPath.endsWith(".zip")) {
// extractZip(itemPath, outputDirPath); // 存在编码问题,暂时不使用
extractUsing7z(itemPath, outputDirPath);
}
else if (itemPath.endsWith(".7z")) {
extractUsing7z(itemPath, outputDirPath);
}
else if (itemPath.endsWith(".rar")) {
extractRar(itemPath, outputDirPath);
}
// 递归处理解压后的内容
processDirectory(outputDirPath, outputDirPath);
// 重新压缩处理后的内容
const outputZip = path_1.default.join(outputDirectory, relativePath, path_1.default.basename(itemPath));
const zip = new adm_zip_1.default();
zip.addLocalFolder(outputDirPath);
zip.writeZip(outputZip);
// 删除临时目录
console.log(`[DELETE] 删除临时目录: ${outputDirPath}`);
fs_1.default.rmSync(outputDirPath, { recursive: true, force: true });
}
else if (DISALLOWED_EXTENSIONS.has(ext) ||
DISALLOWED_KEYWORDS.has(item) ||
isLinuxExecutable(itemPath)) {
console.log(`[DELETE] 删除文件: ${itemPath}`);
deletedItems.push(`文件: ${itemPath}`);
fs_1.default.rmSync(itemPath); // 删除不需要的文件
}
else {
// 将文件复制到对应的输出目录
const outputFilePath = path_1.default.join(outputDirectory, item);
fs_1.default.copyFileSync(itemPath, outputFilePath);
console.log(`[KEEP] 保留文件: ${itemPath} 并复制到 ${outputFilePath}`);
}
}
});
};
// 写入统计文件
const writeLog = (outputDirectory) => {
const logFile = path_1.default.join(outputDirectory, "result_log.txt");
fs_1.default.writeFileSync(logFile, "以下是被删除的目录和文件列表:\n");
fs_1.default.appendFileSync(logFile, deletedItems.join("\n"));
console.log(`[INFO] 统计文件已生成: ${logFile}`);
};
// 主函数
const main = () => {
preTest(); // 测试是否安装了7z和unrar
const inputDirectory = path_1.default.join(process.cwd(), "in"); // 输入文件夹
const outputDirectory = path_1.default.join(process.cwd(), "out"); // 输出文件夹
if (!fs_1.default.existsSync(inputDirectory)) {
console.error(`[ERROR] 输入目录 'in' 不存在,请检查。`);
return;
}
if (fs_1.default.existsSync(outputDirectory)) {
fs_1.default.rmSync(outputDirectory, { recursive: true }); // 清空输出目录
}
fs_1.default.mkdirSync(outputDirectory, { recursive: true });
console.log("[INFO] 开始处理压缩文件...");
processDirectory(inputDirectory, outputDirectory);
writeLog(outputDirectory);
console.log('[INFO] 处理完成!结果保存在 "out" 目录中。');
};
main();
//# sourceMappingURL=process_zip_files.js.map

File diff suppressed because one or more lines are too long

69
package-lock.json generated Normal file
View File

@ -0,0 +1,69 @@
{
"name": "os-exp",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "os-exp",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"adm-zip": "^0.5.16",
"typescript": "^5.6.3"
},
"devDependencies": {
"@types/adm-zip": "^0.5.7"
}
},
"node_modules/@types/adm-zip": {
"version": "0.5.7",
"resolved": "https://registry.npmmirror.com/@types/adm-zip/-/adm-zip-0.5.7.tgz",
"integrity": "sha512-DNEs/QvmyRLurdQPChqq0Md4zGvPwHerAJYWk9l2jCbD1VPpnzRJorOdiq4zsw09NFbYnhfsoEhWtxIzXpn2yw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/node": {
"version": "22.10.6",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-22.10.6.tgz",
"integrity": "sha512-qNiuwC4ZDAUNcY47xgaSuS92cjf8JbSUoaKS77bmLG1rU7MlATVSiw/IlrjtIyyskXBZ8KkNfjK/P5na7rgXbQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.20.0"
}
},
"node_modules/adm-zip": {
"version": "0.5.16",
"resolved": "https://registry.npmmirror.com/adm-zip/-/adm-zip-0.5.16.tgz",
"integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==",
"license": "MIT",
"engines": {
"node": ">=12.0"
}
},
"node_modules/typescript": {
"version": "5.7.3",
"resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.7.3.tgz",
"integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/undici-types": {
"version": "6.20.0",
"resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.20.0.tgz",
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
"dev": true,
"license": "MIT"
}
}
}

22
package.json Normal file
View File

@ -0,0 +1,22 @@
{
"name": "process_zip_files",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"build": "tsc",
"start": "node ./lib/index.js"
},
"bin": {
"pzf": "./lib/index.js"
},
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"adm-zip": "^0.5.16",
"typescript": "^5.6.3"
},
"devDependencies": {
"@types/adm-zip": "^0.5.7"
}
}

252
src/index.ts Normal file
View File

@ -0,0 +1,252 @@
import fs from "fs";
import path from "path";
import { execSync } from "child_process";
import AdmZip from "adm-zip";
const DISALLOWED_EXTENSIONS = new Set([
".exe",
".o",
".class",
".bin",
".dll",
".vcxproj",
".filters",
".user",
".sln",
]);
const DISALLOWED_KEYWORDS = new Set(["a.out", "main", "temp"]);
const DISALLOWED_DIRECTORIES = new Set([
".vs",
".idea",
"__pycache__",
"node_modules",
".git",
"x64",
"x86",
"__MACOSX",
".vscode",
]);
let deletedItems: string[] = [];
// 清理文件名
const sanitizeFileName = (fileName: Buffer): string => {
// 对文件名进行标准化处理,解决编码问题
const decodedName = fileName.toString("utf8");
return decodedName;
};
// 检查是否是压缩文件
const isCompressedFile = (filePath: string): boolean => {
return (
filePath.endsWith(".zip") ||
filePath.endsWith(".7z") ||
filePath.endsWith(".rar")
);
};
// 测试是否安装了7z和unrar
const preTest = () => {
try {
execSync("7z --help");
} catch (e) {
console.error("[ERROR] 7z 未安装,请先安装 7z。");
process.exit(1);
}
try {
execSync("unrar");
} catch (e) {
console.error("[ERROR] unrar 未安装,请先安装 unrar。");
process.exit(1);
}
};
// 检查文件是否可能是Linux可执行文件无后缀的二进制
const isLinuxExecutable = (filePath: string): boolean => {
if (fs.statSync(filePath).isFile() && path.extname(filePath) === "") {
const stats = fs.statSync(filePath);
return (stats.mode & 0o111) !== 0;
}
return false;
};
// 使用7z解压文件
const extractUsing7z = (filePath: string, extractTo: string): void => {
console.log(`[INFO] 使用 7z 解压文件: ${filePath} 到目录: ${extractTo}`);
if (!fs.existsSync(extractTo)) {
fs.mkdirSync(extractTo, { recursive: true });
}
try {
execSync(`7z x "${filePath}" -o"${extractTo}"`);
console.log(`[INFO] 解压完成: ${filePath}`);
} catch (e) {
console.error(`[ERROR] 解压失败: ${e}`);
}
};
// 使用unrar解压文件
const extractRar = (filePath: string, extractTo: string): void => {
console.log(`[INFO] 使用 unrar 解压文件: ${filePath} 到目录: ${extractTo}`);
if (!fs.existsSync(extractTo)) {
fs.mkdirSync(extractTo, { recursive: true });
}
try {
execSync(`unrar x -o+ "${filePath}" "${extractTo}"`);
console.log(`[INFO] 解压完成: ${filePath}`);
} catch (e) {
console.error(`[ERROR] 解压失败: ${e}`);
}
};
/**
*
* @param inputDirectory
* @param outputDirectory
* @deprecated 使
*/
const extractZip = (filePath: string, extractTo: string): void => {
console.log(`[INFO] 解压缩文件: ${filePath} 到目录: ${extractTo}`);
if (!fs.existsSync(extractTo)) {
fs.mkdirSync(extractTo, { recursive: true });
}
const zip = new AdmZip(filePath);
// 遍历所有的文件条目,清理文件名中的非法字符
zip.getEntries().forEach((entry) => {
if (entry.entryName) {
try {
// 清理文件名中的非法字符
const sanitizedName = sanitizeFileName(entry.rawEntryName);
entry.entryName = sanitizedName; // 更新文件名
} catch (e) {
console.error(
`[ERROR] 解压时处理文件名失败: ${entry.entryName}`
);
}
}
});
// 解压文件
zip.extractAllTo(extractTo, true);
};
// 递归处理目录并过滤文件
const processDirectory = (
inputDirectory: string,
outputDirectory: string
): void => {
console.log(`[INFO] 开始处理目录: ${inputDirectory}`);
fs.readdirSync(inputDirectory).forEach((item) => {
const itemPath = path.join(inputDirectory, item);
const stat = fs.statSync(itemPath);
if (stat.isDirectory()) {
// 排除不需要的目录
if (DISALLOWED_DIRECTORIES.has(item)) {
deletedItems.push(`目录: ${itemPath}`);
fs.rmdirSync(itemPath, { recursive: true });
console.log(`[DELETE] 删除目录: ${itemPath}`);
} else {
// 创建对应的输出目录
const outputDirPath = path.join(outputDirectory, item);
if (!fs.existsSync(outputDirPath)) {
fs.mkdirSync(outputDirPath, { recursive: true });
}
processDirectory(itemPath, outputDirPath); // 递归处理子目录
}
} else if (stat.isFile()) {
const ext = path.extname(item).toLowerCase();
// 如果是压缩文件,解压后递归处理
if (isCompressedFile(itemPath)) {
const relativePath = path.relative(
inputDirectory,
path.dirname(itemPath)
);
const outputDirPath = path.join(
outputDirectory,
relativePath,
path.basename(itemPath, path.extname(itemPath)) +
"_extracted"
);
if (!fs.existsSync(outputDirPath)) {
fs.mkdirSync(outputDirPath, { recursive: true });
}
if (itemPath.endsWith(".zip")) {
// extractZip(itemPath, outputDirPath); // 存在编码问题,暂时不使用
extractUsing7z(itemPath, outputDirPath);
} else if (itemPath.endsWith(".7z")) {
extractUsing7z(itemPath, outputDirPath);
} else if (itemPath.endsWith(".rar")) {
extractRar(itemPath, outputDirPath);
}
// 递归处理解压后的内容
processDirectory(outputDirPath, outputDirPath);
// 重新压缩处理后的内容
const outputZip = path.join(
outputDirectory,
relativePath,
path.basename(itemPath)
);
const zip = new AdmZip();
zip.addLocalFolder(outputDirPath);
zip.writeZip(outputZip);
// 删除临时目录
console.log(`[DELETE] 删除临时目录: ${outputDirPath}`);
fs.rmSync(outputDirPath, { recursive: true, force: true });
} else if (
DISALLOWED_EXTENSIONS.has(ext) ||
DISALLOWED_KEYWORDS.has(item) ||
isLinuxExecutable(itemPath)
) {
console.log(`[DELETE] 删除文件: ${itemPath}`);
deletedItems.push(`文件: ${itemPath}`);
fs.rmSync(itemPath); // 删除不需要的文件
} else {
// 将文件复制到对应的输出目录
const outputFilePath = path.join(outputDirectory, item);
fs.copyFileSync(itemPath, outputFilePath);
console.log(
`[KEEP] 保留文件: ${itemPath} 并复制到 ${outputFilePath}`
);
}
}
});
};
// 写入统计文件
const writeLog = (outputDirectory: string): void => {
const logFile = path.join(outputDirectory, "result_log.txt");
fs.writeFileSync(logFile, "以下是被删除的目录和文件列表:\n");
fs.appendFileSync(logFile, deletedItems.join("\n"));
console.log(`[INFO] 统计文件已生成: ${logFile}`);
};
// 主函数
const main = (): void => {
preTest(); // 测试是否安装了7z和unrar
const inputDirectory = path.join(process.cwd(), "in"); // 输入文件夹
const outputDirectory = path.join(process.cwd(), "out"); // 输出文件夹
if (!fs.existsSync(inputDirectory)) {
console.error(`[ERROR] 输入目录 'in' 不存在,请检查。`);
return;
}
if (fs.existsSync(outputDirectory)) {
fs.rmSync(outputDirectory, { recursive: true }); // 清空输出目录
}
fs.mkdirSync(outputDirectory, { recursive: true });
console.log("[INFO] 开始处理压缩文件...");
processDirectory(inputDirectory, outputDirectory);
writeLog(outputDirectory);
console.log('[INFO] 处理完成!结果保存在 "out" 目录中。');
};
main();

17
tsconfig.json Normal file
View File

@ -0,0 +1,17 @@
{
"compilerOptions": {
"target": "ES6",
"module": "CommonJS",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"outDir": "./lib",
"rootDir": "./src",
"resolveJsonModule": true,
"sourceMap": true
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules"]
}