使用node js 编写脚本替换空格为TAB缩进

本文介绍如何使用Node.js编写脚本,递归处理目录下的代码文件,将2空格或4空格自动替换为TAB缩进,提升代码规范性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 递归替换目录下的所有代码文件 , 自动识别 2空格或4空格

replaceToTabs.js


var baseDir = "F:\\opensource\\project";//待替换的目录

const fileUtil = require("./FileUtil.js");
run().catch(function(err){
	console.error( err );
});
async function run(){
	var fileExt =/\.(ts|js|css|html|java|jsp|vue|vuex|less)$/;
	await traversal( baseDir , async function( filePath ){
		if( !fileExt.test( filePath ))
			return;
		let text = await fileUtil.readText( filePath );
		var tabSize = 4;
		var reg ;
		if( /\n(  )[\w\<\.\(\{"']/.test( text ) ){
			tabSize =2 ;
			reg = /\n(  )+/g ;
		}else if( /\n(    )[\w\<\.\(\{"']/.test( text )  ){
			tabSize = 4 ;
			reg =  /\n(    )+/g ;
		}else{
			return;
		}
		let successCnt = 0;
		var newText = text.replace( reg , function( a , $1 , $2 , $3){
			var tabs = ((a.length-1)/tabSize );
			successCnt ++;
			return "\n".padEnd( tabs+1 , "\t");
		} );
		if( successCnt==0)
			return;
		await fileUtil.saveToFile( filePath , newText);
	});
 }

 async function traversal(  dir , fn ){
	let files =  await fileUtil.readdir( dir );
	for( let i=0;i<files.length;i++){
		let fileName = files[i];
		let path = dir + "/" + fileName ;
		var fStat = await fileUtil.getFileStat( path );
		if( fStat.isDirectory()){
			if( /(node_modules|classess)/.test( path)){
				return;
			}
			await traversal( path , fn );
		}else{
			await fn( path , fileName );
		}
	}

}

FileUtil.js

"use strict";

const fs   = require('fs');
const path  = require('path');
module.exports={
	saveToFile , readText ,mkDirIfNotExists , exists , getDirPart , getFileSize , getFileStat ,absPath , rename ,readdir,copyFile,deleteFileSync
};
function getDirPart( filePath ){
	return filePath.replace( /\/[^\\\/]+$/,"" );
}
function saveToFile( filePath , data ){
	if( typeof filePath != "string"){
		throw "error filePath , not a string";
	}
	return new Promise( function( resolve , reject ){
		fs.writeFile( filePath , data , function ( result , err ) {
			if ( err ){
				reject( err );
			}else{
				resolve( true );
			}
		});
	});
}
function readText( filePath  ){
	if( filePath==null )
		return null;
	return new Promise( function( resolve , reject ){
		fs.readFile( filePath , 'utf-8' , function ( err, data ) {
			if ( err ){
				reject( err );
			}else{
				resolve( data );
			}
		});
	});
}
/**
 *
 * @param filePath
 * @return {Promise.<{dev , mode , nlink , uid , gid , rdev , blksize , ino , size , blocks , atime , ctime , birthtime ,isFile:Function ,isDirectory:Function}>}
 */
async function getFileStat( filePath){
	return new Promise(function( resolve , reject ){
		fs.stat( filePath , function( err, stats ){
			if( err)
				reject( err );
			else
				resolve( stats);
		} );
	})
}
async function rename( filePath , newFileFile){
	return new Promise(function( resolve , reject ){
		fs.rename( filePath , newFileFile , function( err, ret ){
			if( err)
				reject( err );
			else
				resolve( ret);
		} );
	})
}
async function copyFile( filePath , newFileFile){
	return new Promise(function( resolve , reject ){
		fs.copyFile( filePath , newFileFile , function( err, ret ){
			if( err)
				reject( err );
			else
				resolve( ret);
		} );
	})
}
function deleteFileSync( filePath  ){
	return fs.unlinkSync( filePath );
}



async function readdir(  filePath ){
	return new Promise(function( resolve , reject ){
		fs.readdir( filePath  , function( err, files ){
			if( err)
				reject( err );
			else
				resolve( files);
		} );
	})
}
async function getFileSize(  filePath ){
	let stat = await  getFileStat( filePath ) ;
	if(!stat.isFile)
		return 0 ;
	return stat.size ;
}
function exists( path ){
	return new Promise( function( resolve  ){
		fs.exists( path  , resolve );
	});
}
async function mkDirIfNotExists( dir ){
	const maxLevel=5;
	let dirs = [];
	while( ! await exists(dir) ){
		dirs.push( dir );
		dir = dir.replace( /[\\\/]$/ , "" );
		let newDir = dir.replace( /[^\\\/]+$/,"" );
		if( newDir === dir )
			throw new Error("取上级文件夹出错");
		dir = newDir ;
		if( dirs.length >maxLevel)
			throw new Error(`创建${dir}失败,最多只能创建${maxLevel}级`);
		if( dir==="" || dir==="/")
			break;
	}
	while( dirs.length> 0 ){
		await mkDir( dirs.pop() );
	}
}
function mkDir( dir ){
	return new Promise( function( resolve, reject ){
		console.info(`创建文件夹${dir}`  );
		fs.mkdir( dir ,function( err ){
			if ( err && err.id !=="EEXIST" ){
				let newErr = new Error( `创建文件夹${dir}失败` );
				newErr.stack = err ;
				reject( newErr );
			}else{
				resolve( true );
				console.info(`创建文件夹${dir}成功`  );
			}
		} );
	});
}

function absPath( relPath  ){
	var fullPath =  path.join( __dirname , relPath);
	return fullPath;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值