【问题标题】:Getting all lines from a file, and put unique lines in a new file从文件中获取所有行,并将唯一行放入新文件中
【发布时间】:2011-11-14 01:19:15
【问题描述】:

使用 PHP 我已经尝试了一整天来完成这项工作。我失败了。我想:

  1. 打开一个目录并读取那里的所有文件。
  2. 逐行读取每个文件的内容(每行是一个没有空格的名称(单列))。
  3. 将每一行放入一个新文件中(逐行换行)。
  4. 删除重复行。
  5. 保存新文件。

对大师来说很容易,对我来说很麻木。

注意:每个文件可能有 500 行长,每行 20 个字符,但只有大约 20 个文件。

提前感谢您的帮助。

再次感谢。 根据下面的帖子,我尝试了

    $topdir = '/home/mycal25/public_html/processed/';


$files = glob($topdir."*.txt"); //matches all text files

$lines = array();
foreach($files as $file)
{
 $lines = array_merge($lines, file($file, FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES));
}
$lines = array_unique($lines);

file_put_contents($topdir."all/all.txt", implode("\n", $lines));

但这并没有奏效... 我尝试了其他几种变体均无济于事..

【问题讨论】:

  • 显示您当前的代码,以便我们帮助您调试它。
  • 我很沮丧,我删除了它。 8 小时无事。

标签: php file


【解决方案1】:

类似:

$lines = array()
foreach ($files as $file) {
    $lines = array_merge($lines, file($file));
}

$lines = array_unique($lines);

$fp = fopen('dest.txt', 'w');
foreach ($lines as $line) {
    fwrite($fp, $line);
}
fclose($fp);

或者,您可以采用不同的方式执行此操作,每次加载新文件时检查唯一条目。这将节省 RAM,但可能会使用更多 CPU。

根据您对 opendir 的评论,您可以执行以下操作:

$files = glob('/home/mycal25/public_html/processed/*');

或坚持opendir()

$topdir = '/home/mycal25/public_html/processed';
$dh = opendir($topdir);
while (($file = readdir($dh)) !== false) {
    $lines = array_merge($lines, file($topdir . '/' . $file));
}

我在某些地方跳过了一些重要的错误检查,只是为了使代码更短且更易于阅读。但是,如果您想确定,请始终检查 opendir/glob/fopen 等的返回值

【讨论】:

  • opendir('/home/mycal25/public_html/processed') 或 exit("无法打开目录!")) { ????
  • 我会这样打开目录然后创建数组吗?
【解决方案2】:

需要指出的是,如果新文件的排序顺序无关紧要,在基于 unix 的系统上使用 sort -u 可能会帮助您非常轻松。

如果您在基于 unix 的主机上运行 PHP,您很可能使用 sortsystem()

【讨论】:

    【解决方案3】:

    8 小时并非白费;这样想,你肯定会讨厌编程!我看到了一个很好的解决方案,可能有一些错误,但所有的思考和大招都在那里。您可能只需要对调试方法进行一些改进。

    这就是我要做的:代替内联函数调用,将它们写成自己的语句并将它们的返回值保存到有意义的变量中。看看这个:

    $topDir = '/home/mycal25/public_html/processed/';
    
    /* Grab names of all needed text files */
    $filePaths = glob($topdir . '*.txt');
    
    $names = array();
    
    foreach($filePaths as $filePath) {
        $fileLines = file($file, FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES);
        $names = array_merge($names, $fileLines);
    }
    
    $uniqueNames = array_unique($names);
    
    $nameList = implode("\n", $uniqueNames);
    
    file_put_contents($topDir . 'all/all.txt', $nameList);
    

    那将是我的个人风格。您现在可以做的是 var_dump() 每个变量并运行您的脚本。通过这样做,您最终将通过输出找出哪个变量不包含您希望它包含的内容。

    此外,请确保已启用所有错误报告。无耻插队:http://www.needtodevelop.com/error-reporting-in-php

    【讨论】:

    • 谢谢。我也试过这个,但仍然没有。我明天再试一次。上面 Tim 的那个可以工作,但是它必须在同一个目录中。我需要从较低目录中的脚本执行此操作。感谢所有的帮助。
    • 解决方案不是我给你写的;我只是给了你一个更容易调试的版本。
    【解决方案4】:
    <?php
    
    $lines = array();
    
    foreach($files as $file)
    {
        $lines = array_merge($lines, array_fill_keys(file($file, FILE_SKIP_EMPTY_LINES), 1));
    }
    
    file_put_contents('file.txt', implode(array_keys($lines)));
    
    ?>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-07
      • 2023-02-20
      • 1970-01-01
      • 1970-01-01
      • 2019-02-07
      • 2019-08-22
      • 1970-01-01
      相关资源
      最近更新 更多