Windows 去掉文件名中的空格
失败的尝试
一般改文件名,我的常规模式是
ls -1(或者dir /b /a-d) | grep 缩小范围 | sed 构造mv/ren语句
然而这次有点问题:
- Windows下,带空格的文件名在cmd里面要用”括起来,这会破坏sed的语句
- 各个文件空格的位置和数量不可知,要用\(pattern\)提取构造很麻烦(至少以我柔弱的sed和正则功力)
想了想觉得问题比较复杂,放弃~~
Windows的解决之道
经过一番搜索,发现原来Windows自己的命令还是可以做一些这类事情的,我一上来思路就是往gnu coreutils上靠,忽略了Windows的bat的用途。 来看看windows for的用法:
C:\>for /? FOR /F ["options"] %variable IN (file-set) DO command [command-parameters] FOR /F ["options"] %variable IN ('string') DO command [command-parameters] FOR /F ["options"] %variable IN (`command`) DO command [command-parameters] filenameset is one or more file names. Each file is opened, read and processed before going on to the next file in filenameset. Processing consists of reading in the file, breaking it up into individual lines of text and then parsing each line into zero or more tokens. The body of the for loop is then called with the variable value(s) set to the found token string(s). By default, /F passes the first blank separated token from each line of each file. Blank lines are skipped. You can override the default parsing behavior by specifying the optional "options" parameter. This is a quoted string which contains one or more keywords to specify different parsing options. The keywords are: eol=c - specifies an end of line comment character (just one) skip=n - specifies the number of lines to skip at the beginning of the file. delims=xxx - specifies a delimiter set. This replaces the default delimiter set of space and tab. tokens=x,y,m-n - specifies which tokens from each line are to be passed to the for body for each iteration. This will cause additional variable names to be allocated. The m-n form is a range, specifying the mth through the nth tokens. If the last character in the tokens= string is an asterisk, then an additional variable is allocated and receives the remaining text on the line after the last token parsed. usebackq - specifies that the new semantics are in force, where a back quoted string is executed as a command and a single quoted string is a literal string command and allows the use of double quotes to quote file names in filenameset.
里面还给出了例子:
FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k
会解析myfile.txt的每一行,无视;打头的,输出逗号或者空格分隔的头三个字符串…活脱脱一个配置文件解析嘛!
解决我的问题
按照例子依样画葫芦,那么我的脚本就是这样的:
@echo off rem 筛选文件,构造文件列表文件 dir /b /a-d *.* > temp.txt rem 循环调用,用奇妙的%*来做参数,所有token都要,分隔符是默认的空格所以不用指定。 for /F "tokens=*" %%* in (temp.txt) do call :sub %%* rem 删除列表文件 del temp.txt goto :eof :sub ren "%*" %1%2%3%4%5%6%7%8%9
最后一个sub写的很傻,我不知道如何获取”%*”里参数的个数,于是就写死9个…如果我想用”_”替换空格的话,会造成很多文件尾部有不少”___”,但是位置一定在尾部,所以用各种方法都很好处理。
学习和折腾的时间远高于写一个perl, python处理的时间了,哈哈…

Discussion