删除文件、文件夹及其子文件夹中的前导空格

删除文件、文件夹及其子文件夹中的前导空格

我想到这个,但不幸的是它不会影响子文件夹中的任何文件/文件夹。

find . -exec rename "s/^\s+//" {} \;

文件夹结构:

foo
|-- \ bar
`-- \ foo1
    |-- \ bar1
    `-- \ foo2
        `-- \ bar2

答案1

重命名需要从下到上进行

问题是您需要重命名目录从下到上。否则,该命令将尝试重命名已移动(重命名)文件夹内的文件和目录,因此无法再找到它们。

这就是可以使用的地方pythonos.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

正如其他答案所指出的那样,主要问题是^锚定小路,而不是文件名的开头。有几种方法可以解决这个问题findrename最安全的方法是使用-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)"

相关内容