PHP将文件复制/发送到正确的文件夹

时间:2017-06-20 16:22:02

标签: php regex

我有很多这样命名的文件:

TRK# 112 WeekDay# 5 From# BOB___Tender_P582895zdf112 TRK# WeekDay# 5 From# BOB___Tender_P588895zdf152 TRK# 115 WeekDay# 5 From# BOB___Tender_P582895zdf714

我想将每个文件发送到自己的文件夹。

示例:

TRK# 112 WeekDay# 5 From# BOB___Tender_P582895zdf112 将进入文件夹112

另外,

TRK# WeekDay# 5 From# BOB___Tender_P588895zdf152不会去任何地方,因为TRK#为空/缺失或不是数字。如果它不是一个数字跳过它。

TRK# 115 WeekDay# 5 From# BOB___Tender_P582895zdf714将进入文件夹115

1 个答案:

答案 0 :(得分:2)

您可以使用preg_match提取数字,然后您可以使用copy制作实际的文件系统副本:

function doCopy($file) {
    preg_match('/TRK\s*#\s*(\d+)/', $file, $matches);
    if (empty($matches[1])) { // no number, skip it
        return false;
    }
    $folder = dirname($file) . DIRECTORY_SEPARATOR . $matches[1];
    if (! is_dir($folder)) { // target directory doesn't exist: make it
        mkdir($folder);
    }
    $target = $folder . DIRECTORY_SEPARATOR . basename($file);
    echo "Copying '$file' into '$target'" . PHP_EOL;
    return copy($file, $target); // actually copy now
}

然后使用此函数对文件进行循环,如下所示:

$files = [
    'TRK# 112 WeekDay# 5 From# BOB___Tender_P582895zdf112',
    'TRK# WeekDay# 5 From# BOB___Tender_P588895zdf152',
    'TRK# 115 WeekDay# 5 From# BOB___Tender_P582895zdf714',
];

foreach ($files as $file) {
    $copied = doCopy($file);
    if (! $copied) {
        echo "Did not copy $file" . PHP_EOL;
    }
}

“魔术”在正则表达式/TRK\s*#\s*(\d+)/中,表示匹配:

  1. 文字字符串“TRK”,
  2. 后跟任意数量的空格
  3. 后跟文字字符串“#”,
  4. 后跟任意数量的空格
  5. 后跟任意数量的数字 - 同时捕获匹配的数字。
  6. 然后我们检查是否存在匹配的数字 - empty测试 - 并复制到以该匹配值命名的目录中。在玩弄路径时我们必须小心。首先,目标目录必须存在。其次,我们需要确保copy可以在相应的目录中找到原始文件,并且我们为其提供包含文件名的目标。超过一半的逻辑用于此开销。

    在Linux机器上运行示例:

    $ mkdir test
    $ touch test/'TRK# 112 WeekDay# 5 From# BOB___Tender_P582895zdf112.pdf'
    $ touch test/'TRK# WeekDay# 5 From# BOB___Tender_P588895zdf152.pdf'
    $ touch test/'TRK# 115 WeekDay# 5 From# BOB___Tender_P582895zdf714.pdf'
    $ cat example.php
    <?php
    
    function doCopy($file) {
        preg_match('/TRK\s*#\s*(\d+)/', $file, $matches);
        if (empty($matches[1])) {
            return false;
        }
        $folder = dirname($file) . DIRECTORY_SEPARATOR . $matches[1];
        if (! is_dir($folder)) {
            mkdir($folder);
        }
        $target = $folder . DIRECTORY_SEPARATOR . basename($file);
            echo "Copying '$file' into '$target'" . PHP_EOL;
        return copy($file, $target);
    }
    
    $files = glob('test/*.pdf');
    foreach ($files as $file) {
        $copied = doCopy($file);
        if (! $copied) {
            echo "Did not copy $file" . PHP_EOL;
        }
    }
    $ php example.php
    Copying 'test/TRK# 112 WeekDay# 5 From# BOB___Tender_P582895zdf112.pdf' into 'test/112/TRK# 112 WeekDay# 5 From# BOB___Tender_P582895zdf112.pdf'
    Copying 'test/TRK# 115 WeekDay# 5 From# BOB___Tender_P582895zdf714.pdf' into 'test/115/TRK# 115 WeekDay# 5 From# BOB___Tender_P582895zdf714.pdf'
    Did not copy test/TRK# WeekDay# 5 From# BOB___Tender_P588895zdf152.pdf
    $ tree test/
    test/
    ├── 112
    │   └── TRK#\ 112\ WeekDay#\ 5\ From#\ BOB___Tender_P582895zdf112.pdf
    ├── 115
    │   └── TRK#\ 115\ WeekDay#\ 5\ From#\ BOB___Tender_P582895zdf714.pdf
    ├── TRK#\ 112\ WeekDay#\ 5\ From#\ BOB___Tender_P582895zdf112.pdf
    ├── TRK#\ 115\ WeekDay#\ 5\ From#\ BOB___Tender_P582895zdf714.pdf
    └── TRK#\ WeekDay#\ 5\ From#\ BOB___Tender_P588895zdf152.pdf