递归地从文件名和目录名中删除所有前导和尾随空格

递归地从文件名和目录名中删除所有前导和尾随空格

我的目录结构如下:

.
├── 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]#}'

相关内容