对“重命名”感到困惑

对“重命名”感到困惑

我有这个文件列表:

$ find .
.
./   sdf.sdf
./  dkfjd  L
./aaa*
./aaa*bbb
./aaa:bbb
./b
./b/c
./b/c/xxx.123

如果我这样做,rename -n -e 's/\*|\:/_/g' -e 's/^\ +//' *我会得到我想要的:

'   sdf.sdf' would be renamed to 'sdf.sdf'
'  dkfjd  L' would be renamed to 'dkfjd  L'
'aaa*' would be renamed to 'aaa_'
'aaa*bbb' would be renamed to 'aaa_bbb'
'aaa:bbb' would be renamed to 'aaa_bbb'

但如果我这样做find . | rename -n -e 's/\*|\:/_/g' -e 's/^\ +//'我会得到:

Reading filenames from STDIN
'./aaa*' would be renamed to './aaa_'
'./aaa*bbb' would be renamed to './aaa_bbb'
'./aaa:bbb' would be renamed to './aaa_bbb'

为什么第二个命令看不到以空格开头的目录?

我也尝试过,find . -print0 | rename -n -0 -e 's/\*|\:/_/g' -e 's/^\ +//'但这没有什么区别。

我需要rename在一棵大树上运行;还有其他方法可以递归到子目录吗?

注意:最终我将使用mdfindnot来使用它find,所以我不能使用该-exec选项。

答案1

这将重命名文件和目录(嗯,任何匹配的东西,真的)。我已经指定-depth,在安全处理内容之前不会重命名更高级别的目录。

find . -depth | rename -n -e 'y{*:}{_}; s{(?<=/)\s+(?!.*/.*$)}{}'

重命名是由两个 RE 构建的。 (我的rename仅接受一个-e {RE}参数,因此我将这两个操作连接到一个参数中。)

第一个很简单:用ory{*:}{_}代替(又名 Unix )。*:_tr

第二种更复杂并且使用向后看和向前看以匹配必要的组件。它表示要处理的表达式\s+应紧接在 之前/,并且后面不能跟在/文件名其余部分的任何位置。

输出

rename(./  dkfjd  L, ./dkfjd  L)
rename(./aaa*, ./aaa_)
rename(./aaa*bbb, ./aaa_bbb)
rename(./   sdf.sdf, ./sdf.sdf)
rename(./aaa:bbb, ./aaa_bbb)

相关内容