REPY.EXE [VERSION 1.1]
下载:
- 1.png
- (28.85 KiB) 已下载 1014 次
摘要:
=============================================================================
兼容PERL正则语法的文件复制工具。支持指定目录,子目录搜寻,对匹配到的文件亦可
进行正则更名复制。同时支持高亮彩显。
支持 IGNORECASE, SINGLELINE, MULTILINE 等常见匹配模式。支持命名分组, 条件表
达式,递归表达式等多种高级特性。本工具引用了DEELX正则库版权归DEELX作者所有,
其余代码版权归本人所有。
DEELX正则库deelx.h下载地址
http://www.regexlab.com/deelx/
=============================================================================
语法:
DEELX 正则表达式中标准的字符集合有:
字符集合
说明
.
小数点可以匹配除了换行符(\n)以外的任意一个字符
\w
可以匹配任何一个字母或者数字或者下划线
\W
W大写,可以匹配任何一个字母或者数字或者下划线以外的字符
\s
可以匹配空格、制表符、换页符等空白字符的其中任意一个
\S
S大写,可以匹配任何一个空白字符以外的字符
\d
可以匹配任何一个 0~9 数字字符
\D
D大写,可以匹配任何一个非数字字符
[:alpha:]
POSIX 格式,可以匹配任何一个字母
[:^alpha:]
POSIX 否定格式,可以匹配任何一个字母以外的字符
如果正则表达式匹配模式为 SINGLELINE,小数点可以匹配包含换行符在内的任一字符。更多详情,参见正则表达式匹配模式。
DEELX 支持的 POSIX 字符集合定义有:
POSIX 字符集合
说明
[:alnum:]
任何一个字母或数字(A - Z, a - z, 0 - 9)
[:alpha:]
任何一个字母(A - Z, a - z)
[:ascii:]
任何一个 ASCII 范围内字符(\x00 – \x7F)
[:cntrl:]
任何一个控制字符(\x00 – \x1F, \x7F)
[:digit:]
任何一个数字(0 – 9)
[:print:]
任何一个可显示的 ASCII 字符(\x20 – \x7E)
[:space:]
任何一个空白字符(\x09 – \x0D, \x20)
[:graph:]
任何一个可显示的 ASCII 字符,不包含空格(\x21 – \x7E)
[:lower:]
任何一个小写字母(a – z)
[:punct:]
可显示字符 [:print:] 中除去字母数字 [:alnum:]
[:upper:]
任何一个大写字母(A – Z)
[:xdigit:]
任何一个十六进制数字(0 - 9, A - F, a - f)
[:blank:]
空格或者制表符(\x20, \x09)
用法:
-----------------------------------------------------------------------------
repy [match expression] [format expression]
-----------------------------------------------------------------------------
/r Recursive subdirectories REM 递归子目录
/f Force copy REM 强制复制文件
-----------------------------------------------------------------------------
示例:
-----------------------------------------------------------------------------
REM 递归子目录复制到H盘test目录下
repy /r (.*\.tlog) h:\test\$1
REM 将制定目录文件复制到制定目录,请转义斜杠
repy /f E:\\li\\desk\\新建文件夹\\src\\Release\\1.txt H:\1.txt
-----------------------------------------------------------------------------
英译:
-----------------------------------------------------------------------------
REGULAR COPY TOOLS, COPYRIGHT@2017~2019 BY HAPPY
-----------------------------------------------------------------------------
repy [match expression] [format expression]
-----------------------------------------------------------------------------
/help Show help information
/r Recursive subdirectories
/f Force copy
-----------------------------------------------------------------------------
2017-02-25
/*
REGULAR COPY TOOLS, COPYRIGHT@2016~2018 BY HAPPY, VERSION 1.1
REPY.EXE
*/
#include "deelx.h"
#include <windows.h>
#include <direct.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
/***************定义全局变量*************/
//百分比标记
char perMARKS[51];
//进度条容器
const char proGRESS[128]="[ ]\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
//定义路径名最大长度(字节)
#define PATH_SIZE 512
//定义文件名最大长度(字节)
#define FNAME_SIZE 1024
//主窗口句柄
HANDLE handle_out;
//定义帮助说明
#define HELP_INFORMATION "\
-----------------------------------------------------------------\n\
REGULAR COPY TOOLS, COPYRIGHT@2017~2019 BY HAPPY, VERSION 1.1\n\
-----------------------------------------------------------------\n\
repy [match expression] [format expression]\n\
-----------------------------------------------------------------\n\
/h Show help information\n\
/r Recursive subdirectories\n\
/f Force copy\n\
-----------------------------------------------------------------\n\
2017-02-25"
/***************功能函数群***************/
char* strrstr(const char *dst, const char *src)
{
assert(dst);assert(src);
const char *pdst=dst, *psrc=src;
char *ret=NULL;
while(*dst){
while(*pdst==*psrc){
if(*pdst=='\0'){
return ret=(char*)dst;
}else{
pdst++;
psrc++;
}
}
if(*psrc=='\0'){ret=(char*)dst;}
pdst=++dst;
psrc=src;
}
return ret;
}
//进度条回调函数
DWORD CALLBACK CopyProgressRunTim(
LARGE_INTEGER tFileSize,
LARGE_INTEGER tTransferred,
LARGE_INTEGER StreamSize,
LARGE_INTEGER Streamferred,
DWORD StreamNumber,
DWORD CallbackReason,
HANDLE SourceFile,
HANDLE DestinationFile,
LPVOID lpData
)
{
//计算进度
int i=(tFileSize.LowPart<=0) ?100 :(tTransferred.LowPart*1.0)/(tFileSize.LowPart)*100, j=i>>1;
//显示递增进度
while((j--)>perMARKS[0] && !(perMARKS[j])){perMARKS[j]=TRUE; fputc('=', stdout);}
perMARKS[0]=i>>1;
//显示进度百分比
fprintf(stdout, "%02d%%\b\b\b", i);
//回调
return PROGRESS_CONTINUE;
}
//正则命名函数
void ReCopy(
int FLAG, //复制模式开关
const char* Org_Path, //工作目录
char* RE_Match, //要匹配的正则
char* RE_Format //要更名的正则
)
{
//设置工作目录
_chdir(Org_Path);
struct _finddata_t FileS;
intptr_t handle=_findfirst("*",&FileS);
bool M=(handle==-1)?TRUE:FALSE;
while(!M){
if(
(strcmp(FileS.name, ".")==0) ||
(strcmp(FileS.name,"..")==0)
){
M=(_findnext(handle, &FileS)!=0)?TRUE:FALSE;
continue;
}
//匹配正则
CRegexpT<char> regexp(RE_Match);
MatchResult result=regexp.Match(FileS.name);
//执行复制
if(result.IsMatched()){
//正则替换
char* tpSTR=regexp.Replace(FileS.name, RE_Format);
//绘进度条
SetConsoleTextAttribute(handle_out, 1|4|8); //紫色
fprintf(stdout, "Copy... ");
SetConsoleTextAttribute(handle_out, 2|8); //绿色
fprintf(stdout, "%s -> %s\n", FileS.name, tpSTR);
SetConsoleTextAttribute(handle_out, 2|4|8); //黄色
fputs(proGRESS, stdout);
//初始化进度数组
memset(perMARKS, FALSE, 50);
//强制删除
if(FLAG==0x01){remove(tpSTR);}
//复制文件
if(!CopyFileEx(FileS.name, tpSTR, (LPPROGRESS_ROUTINE)CopyProgressRunTim, NULL, FALSE, COPY_FILE_FAIL_IF_EXISTS)){
SetConsoleTextAttribute(handle_out, 4|8);
fprintf(stdout, "Failed to copy, Check if the target path exists");
}
SetConsoleTextAttribute(handle_out, 1|2|4|8);//白色
fputs("\n\n", stdout);
//释放字串
CRegexpT<char>::ReleaseString(tpSTR);
}
M=(_findnext(handle, &FileS)!=0)?TRUE:FALSE;
}
_findclose(handle);
//递归子目
if(FLAG==0x02){
handle=_findfirst("*.*", &FileS);
M=(handle==-1)?true:false;
while(!M){
if(FileS.attrib & _A_SUBDIR){
if(
(strcmp(FileS.name, ".")!=0) &&
(strcmp(FileS.name,"..")!=0)
){
//正则复制
ReCopy(FLAG, FileS.name, RE_Match, RE_Format);
}
}
M=(_findnext(handle, &FileS)!=0);
}
_findclose(handle);
}
//还原目录、释放内存
_chdir(Org_Path);
}
/*************MAIN主函数入口*************/
int main(int argc, char ** argv)
{
//检查输入参数是否存在错误
if(
(argc!=3 && argc!=4 ) ||
(argc==3 && argv[1][0]=='/') ||
(argc==4 && argv[1][0]!='/') ||
(
argc>1 &&
argv[1][0]=='/' &&
(
argv[1][1]=='?'||
argv[1][1]=='h'||
argv[1][1]=='H'
)
)
){
fputs(HELP_INFORMATION, stdout);
exit(0);
}
//模式变量
int i=1, FLAG=0x00;
//解析开关
if(argv[i][0]=='/' && argc==4){
switch(argv[i][1])
{
case 'f':
case 'F':
FLAG=0x01, i++;
break;
case 'r':
case 'R':
FLAG=0x02, i++;
break;
default:
//无法识别的开关
fprintf(stderr, "Unrecognized switch '%s'\n", argv[i]);
exit(1);
}
}
handle_out=GetStdHandle(STD_OUTPUT_HANDLE);
char* Org_Path=(char*)calloc(PATH_SIZE, sizeof(char));
char* p=strrstr(argv[i], "\\\\");
if(p!=NULL){
strncpy_s(Org_Path, PATH_SIZE, (const char*)argv[i], (int)p-(int)argv[i]);
ReCopy(FLAG, Org_Path, p+2, argv[i+1]);
}else{
ReCopy(FLAG, ".", argv[i], argv[i+1]);
}
return 0;
}