我想到这个,但不幸的是它不会影响子文件夹中的任何文件/文件夹。
find . -exec rename "s/^\s+//" {} \;
文件夹结构:
foo
|-- \ bar
`-- \ foo1
|-- \ bar1
`-- \ foo2
`-- \ bar2
答案1
重命名需要从下到上进行
问题是您需要重命名目录从下到上。否则,该命令将尝试重命名已移动(重命名)文件夹内的文件和目录,因此无法再找到它们。
这就是可以使用的地方python
,os.walk()
与topdown=False
在一个小的脚本中:
#!/usr/bin/env python3
import os
import shutil
import sys
for root, dirs, files in os.walk(sys.argv[1], topdown=False):
for f in files:
if f.startswith(" "):
shutil.move(root+"/"+f, root+"/"+f.strip())
for dr in dirs:
if dr.startswith(" "):
shutil.move(root+"/"+dr, root+"/"+dr.strip())
使用
- 将脚本复制到一个空文件中,另存为
no_space.py
通过命令运行:
python3 /path/to/no_space.py /path/to/directory/to/rename
答案2
正如其他答案所指出的那样,主要问题是^
锚定小路,而不是文件名的开头。有几种方法可以解决这个问题find
:rename
最安全的方法是使用-execdir
代替 ,-exec
这样所有路径组件都会缩减为./
,然后替换模式\./\s+
另外,如果你要重命名目录可能包括要重命名的其他文件/目录的祖先,那么你应该进行深度优先遍历。
把它放在一起,
find . -depth -name ' *' -execdir rename -vn -- 's#\./\s+##' {} +
或者(功能相同,但更容易看出发生了什么)使用零长度的“后视”作为路径分隔符
$ find . -depth -name ' *' -execdir rename -vn -- 's#(?<=\./)\s+##' {} +
./ bar2 renamed as ./bar2
./ foo2 renamed as ./foo2
./ bar1 renamed as ./bar1
./ foo1 renamed as ./foo1
./ bar renamed as ./bar
[注意:-n
一旦您确定它可以满足您的要求,请将其删除]
答案3
我认为问题在于 find 的输出格式,其中包含完整路径。因此对于 bar2,您将得到
./ foo1/ foo2 /bar2
重命名将无法正确理解。
一种解决方案是使用脚本以递归方式执行每个文件夹,如下所示:
#!/bin/bash
# if argument given consider it is the directory to parse
if [ -n "$1" ]; then
cd "$1"
fi
# rename all files in current folder
find . -maxdepth 1 -printf '%f\0' | xargs -0r -n 1 rename -nono 's/^\s+//'
# No, repeat for all subfolders with current script (we are in the subfolder)
find . -maxdepth 1 -type d -not -name '.' -print0 | xargs -0r -n 1 "$(readlink -f $0)"