如何将所有隐藏的文件夹/文件更改为在多个子目录中可见

时间:2017-10-01 21:21:35

标签: linux perl rename file-rename

我在一个目录中有数百个子目录,其中都有隐藏文件,我需要删除它们开头的句点以使它们可见。我找到了一个命令进入每个目录并更改它们以使它们可见但我需要知道如何使这个命令在一个目录中运行。

rename 's/\.//;' .*

我已经尝试了大约一个小时来修改它以便在一个级别上工作,但是不能理解Perl字符串足以完成它。如果有人可以提供帮助,我相信这很简单,而且我无法找到合适的答案。

2 个答案:

答案 0 :(得分:4)

这需要一个支持+的查找(可以使用\;代替rename多次),但即使POSIX find也指定它:

find -mindepth 1 -depth -exec rename -n 's{/\.([^\/]*$)}{/$1}' {} +
  • -depth选项可防止在重命名目录中的所有文件之前重命名目录
  • -mindepth 1阻止find尝试重命名当前目录.
  • -n只是打印要重命名的内容而不是实际重命名(必须删除才能重命名)。
  • 正则表达式删除没有正斜杠的最后一个句点,如果前面有正斜杠。

rename不会覆盖现有文件,除非使用-f(" force")选项。

对于像这样的测试目录结构:

.
├── .dir1
│   ├── .dir2
│   │   ├── .dir3
│   │   │   └── .file2
│   │   └── .file1
│   ├── file3
│   └── .file6
├── dir5
│   └── .file5
├── .file4
├── test1.bar
└── test1.foo

输出

rename(./dir5/.file5, ./dir5/file5)
rename(./.file4, ./file4)
rename(./.dir1/.file6, ./.dir1/file6)
rename(./.dir1/.dir2/.file1, ./.dir1/.dir2/file1)
rename(./.dir1/.dir2/.dir3/.file2, ./.dir1/.dir2/.dir3/file2)
rename(./.dir1/.dir2/.dir3, ./.dir1/.dir2/dir3)
rename(./.dir1/.dir2, ./.dir1/dir2)
rename(./.dir1, ./dir1)

,删除-n后的结果是

.
├── dir1
│   ├── dir2
│   │   ├── dir3
│   │   │   └── file2
│   │   └── file1
│   ├── file3
│   └── file6
├── dir5
│   └── file5
├── file4
├── test1.bar
└── test1.foo

答案 1 :(得分:3)

safely_unhide

#!/usr/bin/perl
use strict;
use warnings;
use File::Basename qw( fileparse );
for (@ARGV) {
   my $o = $_;

   my ($fn, $dir_qfn) = fileparse($_);
   $fn =~ s/^\.//
      or next;

   my $n = "$dir_qfn/$fn";
   if (stat($n)) {
      warn("Skipping \"$o\": \"$n\" already exists\n");
      next;
   }
   elsif (!$!{ENOENT}) {
      warn("Skipping \"$o\": Can't stat \"$n\": $!\n");
      next;
   }

   rename($n, $o)
      or warn("Skipping \"$o\": Can't rename to \"$n\": $!\n");
}

用法:

find -type f -exec safely_unhide {} +          # Supports all file names. Requires GNU find
find -type f | xargs safely_unhide             # Doesn't support newlines in file names.
find -type f -print0 | xargs -0 safely_unhide  # Supports all file names.

如果您想要重命名隐藏的目录,请删除-type f并添加-depth