迭代一系列目录并以特殊方式对每个目录执行 mkdir

时间:2021-05-03 13:05:16

标签: perl

我有一个目录数组。我想遍历数组并对其执行 mkdir

foreach my $dir (@dirs) {
    print $fh "mkdir -p $dir\n";
}

我想减少文件中的字符数。所以我想使用 mkdir 的特殊情况,它允许使用 {name,name,name} 并且它将创建所有这些。因此,例如,而不是:

mkdir -p /a/b/c/e/f
mkdir -p /a/b/c/e/g
mkdir -p /a/b/c/e/h

它会做:

mkdir -p /a/b/c/e/{f,g,h}

目录已处于其规范模式,因此此处不需要 realpath

迭代数组 @dirs 并执行此操作的最佳方法是什么?我想我需要在每一个上使用 dirname ,然后收集每一个“集合”,然后在它上面做 mkdir 。但最好的方法是什么?

2 个答案:

答案 0 :(得分:3)

可以通过两个循环来完成:

use strict;

# your Filehandle
my $fh;
my @dirs = qw" /a/b/c/e/f
               /a/b/c/e/g
               /a/b/c/e/h ";

# use a hash for temporary hold the dirs per path
my %split_dirs;

for (@dirs) {
    # Split the current path into the path (..../) and the dir behind.
    my ($current_path, $current_dir) = /^(.*\/)(.*)$/;
    # if there where already a dir for this path, add this one and go
    # to the next iteration else there would be created a new one.
    push(@{$split_dirs{$current_path}}, $current_dir);
}

# Now you can join the values per path and print out.
print $fh "mkdir -p $_\{" .
          join(",", @{$split_dirs{$_}}) .
          "\}\n"
    for (keys %split_dirs);

或者更紧凑一点:

# ...

my %split_dirs;

/^(.*\/)(.*)$/,
    push(@{$split_dirs{$1}}, $2)
    for (@dirs);

print $fh "mkdir -p $_\{" .
          join(",", @{$split_dirs{$_}}) .
          "\}\n"
    for (keys %split_dirs);

输出

mkdir -p /a/b/c/e/{f,g,h}

答案 1 :(得分:2)

这就是 library 的设计目的:

<块引用>

我写这个模块的最初动机是压缩数字 显示服务器名称列表所需的字符数, 例如将文本消息的主题发送到寻呼机/移动电话。 如果我从一长串遵循标准命名的服务器开始 约定,例如:

app-dc-srv01 app-dc-srv02 app-dc-srv03 app-dc-srv04 app-dc-srv05
app-dc-srv06 app-dc-srv07 app-dc-srv08 app-dc-srv09 app-dc-srv10

运行完这个模块后,可以显示更多 有效地在寻呼机上:

app-dc-srv{0{1,2,3,4,5,6,7,8,9},10}

该算法对目录也很有用:

/usr/local/{bin,etc,lib,man,sbin}

请注意当前的限制:

<块引用>

当前的算法非常丑陋,只会压缩以类似文本开头和/或结尾的字符串。我一直在研究一种使用加权树的新算法。

相关问题