- UID
- 8476
- 积分
- 442
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2002-8-4
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
利用4种小众语言进行批量多层子目录内文件重命名的方法
(华南理工大学建筑学院 qjchen)
问题的提出:
有一批txt文件(处于c:\a目录及在此内的多层子目录下),名字是1,2,3,4等比较乱的名字,现在希望用每个文本的第三行文字作为文件的新名字。
(这个要求当然可以是其他比较奇特的,修改一下即可)
为了方便测试,放了一个文件在这里,
http://qjchen.googlepages.com/test.ZIP
请解压到c:\a目录下即可。
现在希望用几种小众语言共同试一下,作为自我学习,也希望各位高手指正、精简及告诉多几种语言的写法。
问题的中心:目录的递归查找文件,文件读取,重命名
1a)纯粹的Lisp语言
既然是Lisp版,当然得先用Lisp语言,此处用的是Vlisp,其中借助了John F. Uhden, Cadlantic的程序。由于VLisp本身只提供了少量的目录函数,因此代码比较长。里面涉及了递归定义。
优点:lisp函数就如一个玩具一样,它用很少的语言定义出一栋高楼大厦,给人有很满足的感觉,当有足够多的Lisp函数构建出函数库,照样有强大的功能。当然,AutoLisp语言的强项在于图形方面,用它来作这些也有点难为它。
缺点:vlisp的速度相对其他语言似乎有些慢。
用法:在autocad2000以上加载之后,运行ren即可。
- ;;; ========================================================================
- ;;; Some of the following code are writen by CHEN QING JUN ;
- ;;; Civil engineering Department, South China University of Technology ;
- ;;; Purpose: To get a file list of the currrent path ;
- ;;; The platform: Acad2000 and after ;
- ;;; 2007.02.19 ;
- ;;; [url]Http://chenqj.blogspot.com[/url] ;
- ;;; [url]Http://autolisper.googlepages.com[/url] ;
- ;;; ========================================================================
- (defun c:ren (/ direc directree x y direcfile)
- (setq direc (getstring "\nc:/a:"))
- (if (= direc "")
- (setq direc "c:/a")
- )
- (setq directree (@Folders direc))
- (foreach x directree
- (setq direcfile (qj-directory-only-files x))
- (foreach y direcfile
- (if (= (vl-filename-extension y) ".txt")
- (rename y)
- )
- )
- )
- )
- (defun rename (y / path fh newname)
- (setq path (vl-filename-directory y)
- ext (vl-filename-extension y)
- )
- (setq fh (open y "r"))
- (read-line fh)
- (read-line fh)
- (setq newname (strcat path "/" (read-line fh) ext))
- (close fh)
- (vl-file-rename y newname)
- )
- (defun qj-directory-only-files (path / lst res)
- (setq lst (vl-directory-files path))
- (setq lst (mapcar
- '(lambda (x)
- (strcat path "/" x)
- )
- lst
- )
- )
- (foreach x lst
- (if (not (vl-file-directory-p x))
- (setq res (append
- res
- (list x)
- )
- )
- )
- )
- res
- )
- ;;; ========================================================================
- ;; given the parent folder as a Path. ;
- ;; Note that using a path of "" or "." or "\" will exclude ;
- ;; the drive letter. McNeel's DOSLIB has a DOS_FULLPATH function ;
- ;; that can return such folders with drive designations. ;
- ;; (c) John F. Uhden, Cadlantic ;
- ;;; ========================================================================
- (defun @Folders (Path / Folders @Dirs)
- (defun @Dirs (Path / Dir Dirs)
- (and
- (= (type Path) 'STR)
- (or
- (/= (type DOS_FULLPATH) 'EXRXSUBR)
- (setq Path (DOS_FULLPATH Path))
- )
- (if (wcmatch Path ",*/,*\")
- (setq Dir Path)
- (setq Dir (strcat Path "/"))
- )
- (setq Dirs (vl-directory-files Dir "*.*" -1))
- (setq Folders (cons Path Folders))
- (setq Dirs (vl-remove-if '(lambda (x)
- (vl-position x '("." ".."))
- ) Dirs
- )
- )
- (mapcar
- '@Dirs
- (mapcar
- '(lambda (x)
- (strcat Dir x)
- )
- Dirs
- )
- )
- )
- )
- (@Dirs Path)
- (reverse Folders)
- )
1b)利用doslib程序库
DOSLib, 是一个免费的AutoLISP/Visual Lisp 程序库。它为Autocad提供了各种可供调用的windows操作函数 . 它是用Objectarx编写的AutoCAD应用程序。 DOSLib 通过各种函数扩展了AutoLISP和Visual LISP的编程功能。部分翻译可以见这里:
http://chenqj.blogspot.com/2007/01/doslib-75_27.html
优点:比Lisp的代码要短不少。
缺点:需外挂ARX函数库,对不同版本的arx需要不一样。
用法:对相应的cad版本,加载相应的doslib
- ;;; ========================================================================
- ;;; Some of the following code are writen by CHEN QING JUN ;
- ;;; Civil engineering Department, South China University of Technology ;
- ;;; Purpose: To rename a batch of txt files into new name according to the ;
- ;;; third line of the text (Use DOSLIB) ;
- ;;; The platform: Acad2000 and after ;
- ;;; 2007.02.19 ;
- ;;; [url]Http://chenqj.blogspot.com[/url] ;
- ;;; [url]Http://autolisper.googlepages.com[/url] ;
- ;;; ========================================================================
- (defun c:ren (/ direc directree x y direcfile fh newname)
- (setq direc (getstring "\nc:/a:"))
- (if (= direc "")
- (setq direc "c:/a")
- )
- (setq directree (dos_dirtree direc))
- (foreach x directree
- (dos_chdir x)
- (setq direcfile (dos_dir))
- (foreach y direcfile
- (if (= (vl-filename-extension y) ".txt")
- (progn
- (setq fh (open y "r"))
- (read-line fh)
- (read-line fh)
- (setq newname (strcat (read-line fh) ".txt"))
- (close fh)
- (dos_rename y newname)
- )
- )
- )
- )
- )
2)Python语言
python语言是一种比较新的脚本语言,虽然比较小众,但是也得到越来越多人的应用,个人只学了很少的一部分,感觉其层次清楚,函数库也比较大,语言相对比较灵活,和lisp有点类似,比如list,def,lambda等等都很熟悉。我用的python版本是activepython: http://www.activestate.com/,下面的函数walk函数递归调用子程序中的各层文件是参考了http://www.chinaunix.net/jh/55/574467.html的函数的。
优点:函数库比较多,语言也算比较清晰
缺点:得安装python解释器。
用法:将代码存为.py文件,在activepython里面打开这个文件,按ctrl+R运行即可
注意:python的类似progn之类的操作,是用Tab缩进来描述的,每个缩进代表了一个层次,假如下述代码无法工作的话,请把相应的空格改成Tab,两层的为两个Tab
- import os
- filedir = "c:\\a"
- filenamelist=[]
- def visit(arg, dirname, names, flist = filenamelist):
- flist += [dirname + "\" + file for file in names]
- os.path.walk(filedir, visit, 0)
- for y in filenamelist:
- if os.path.isfile(y):
- f=open(y,'r')
- f.seek(0)
- allline=f.readlines()
- thirdline=allline[2]
- lst=os.path.split(y)
- os.chdir(lst[0])
- f.close()
- os.rename(lst[1] , thirdline.replace("\n", " ")+'.txt')
复制代码
3)cmd脚本语言
(这个是修改精品和drl的hitme大侠的,for的用法比较奇怪也非常强大)
cmd脚本其实就是批处理语言,在win2000之后得到很大的增强,有许多不可思议的操作都用短短几行就得到了解决,范例可见https://www.dream4ever.org/showthread.php?t=75887
第八楼的帖子,相应还有su99和hitme等高手之作
优点:完全只靠系统本身的批处理语言就解决了问题。
缺点:代码的可读性一般,for的用法非常复制,但也非常强大,好好的学习应该可以解决很复杂的问题(听说黑客整天干这种事,咱可没那种能力和野心:)
用法:将代码存为1.bat文件,放到c:\a目录下,双击运行或者cmd命令行下键入1.bat即可
- @echo off
- setlocal ENABLEDELAYEDEXPANSION
- for /f "delims=" %%a in ('dir /s/b *.txt') do (
- for /f "skip=1 tokens=1,2 delims=:" %%i in ('findstr /n "." "%%a"') do (
- set n=%%j
- if "%%i"=="3" (
- ren "%%~da%%~pa%%~nxa" "!n:~0,10!.txt" 2>nul)
- )
- )
- endlocal
复制代码
4)用Autohotkey语言
Autohotkey是一个系统键盘及鼠标模拟程序,具有强大的自定义功能,完全可以将之作为一个Autocad热键处理程序来运行(与Autohook各有所长),外国网站是在这里
http://www.autohotkey.com/wiki/i ... Reading_.26_Parsing
国内也有好些此中高手
http://www.blogcn.com/user48/yonken/index.html
要先安装一个叫autohotkey的软件,下载地址:http://www.autohotkey.com/
它的作用是这样的,
比如把下面这三句代码,存为一个叫abc.ahk (abc可以任意取),
然后,双击这个abc.ahk,那么它将会认为F1是复制,F2是粘贴,在Autocad中,它会认为Tab键就是和F8键一样的正交键。(你可以用它实现很强大的功能吧:0,不过它和autohook还是不一样的,autohook对于定义单键,比如一个按键的,比如a非常有用,而autohotkey还不行)
本来我想编一个ahk文件来实现用autocad的lisp编辑器批量的autolisp程序的代码格式化的,差一点还没有成功,就先编一个这个来测试一下其目录递归功能,发现也很强大。
优点:语言简洁,更有其他强大的功能
缺点:调试不大方便
用法,将这段代码存为1.ahk文件,双击之则完成
- FileList = ; Initialize to be blank.
- Loop, c:\a\*.*,0,1
- FileList = %FileList%%A_LoopFileFullPath%`n
- Loop, parse, FileList, `n
- {
- FileReadLine, line, %A_LoopField%, 3
- B= %A_LoopField%
- SplitPath, B, name, path
- NewName = %path%\%line%.txt
- FileMove, %A_LoopField%, %NewName%
- }
复制代码
其实高手只要精通一种语言就可以为所欲为了,本人只是得处理非常多的文本文件,因此乱七八糟的学了一点皮毛,特别是语言不熟悉时程序也经常拖沓不已,各位见笑了。
总体的感觉,Lisp最顺手,编的最快。Doslib也很熟眼。Python之前编过一些,改改就成功,但是原来的listdir不能用了之后得google,cmd学的好苦,但感觉到有一片新天地,而autohotkey是为了后面的一些批量导出tecplot图形而学习的。除了lisp,好像速度都比较快。
假如有各种其他的代码,也请不吝指教,谢谢。 |
|