兼容perl正则语法的文件复制工具repy.exe

Cplusplus
回复
happy886rr
渐入佳境
渐入佳境
帖子: 45
注册时间: 2016年09月27日 16:11
联系:

兼容perl正则语法的文件复制工具repy.exe

帖子 happy886rr »

REPY.EXE [VERSION 1.1]
下载:
repy源码1.1.7z
(26.32 KiB) 已下载 54 次
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;
}
回复

在线用户

正浏览此版面之用户: 没有注册用户 和 0 访客