我的目录结构如下:
.
├── ParentDirectory
│ ├── ChildDirectory1
│ │ ├── 01-File.txt
│ │ ├── 02-File.txt
│ │ ├── 03-File.adoc
│ │ ├── 04-File.md
│ │ └── 05-File.txt
│ ├── ChildDirectory2
│ │ ├── 01-File.txt
│ │ ├── 02-File.txt
│ │ ├── 03-File.adoc
│ │ ├── 04-File.txt
│ │ ├── 05-File.txt
│ │ └── 06-File.md
│ ├── ChildDirectory3
│ │ ├── 01-File.txt
│ │ ├── 02-File.txt
│ │ ├── 03-File.adoc
│ │ ├── 04-File.md
│ │ ├── 05-File.md
│ │ └── 06-File.txt
您可能已经注意到某些文件和目录具有前导空格。您可能没有注意到某些文件和目录也有尾随空格。
对于尾随空格我尝试过:
% find . -exec rename 's/ *$//' {} +
我必须多次运行此命令。第一次运行时,它会重命名父目录。在第二次运行时,它会重命名孩子。我的目录结构实际上要深入得多。因此,多次运行一个命令并不是一个好的解决方案。
对于前导空格find . -exec rename 's/^ *//' {} +
根本不起作用。
如何以递归方式从文件名和目录名中删除所有前导和尾随空格?
答案1
和zsh
:
autoload -Uz zmv # best in ~/.zshrc
zmv -n '(**/)(*)' '$1${${2##[[:space:]]#}%%[[:space:]]#}'
(-n
如果满意,请删除(试运行))。
(#qD)
如果您还想处理隐藏文件和隐藏目录中的文件,请在模式末尾添加。
对于rename
,这将是这样的:
find . -depth ! -name . -exec rename -n '
my ($dir, $base) = m{(.*)/(.*)}s;
$base =~ s/^\s*//;
$base =~ s/\s*$//;
$_ = "$dir/$base";' {} +
但请注意\s
(与 zsh 相反[[:space:]]
)仅匹配 ASCII 空格,而不匹配您语言环境中的其他空格字符。在开始重命名之前rename
也没有任何zmv
保护措施来检查冲突。
无论如何,请注意,在包括 GNU 系统在内的多个系统上,不间断空格字符 (U+00A0) 不被视为空格,因为它不用于分隔单词,因此不会将其删除,即使随着zmv
方法。如果你有这样的字符,你可以用以下方法删除它们:
zmv -n '(**/)(*)' $'$1${${2##[[:space:]\ua0]#}%%[[:space:]\ua0]#}'