Есть ли простой способ найти и удалить повторяющиеся строки из файла CSV?
Пример файла test.csv:
row1 test tyy...... row2 tesg ghh row2 tesg ghh row2 tesg ghh .... row3 tesg ghh row3 tesg ghh ... row4 tesg ghh
Ожидаемые результаты:
row1 test tyy...... row2 tesg ghh .... row3 tesg ghh ... row4 tesg ghh
Где я могу начать делать это с помощью PHP?
Прямоточным методом было бы читать файл по очереди и отслеживать каждую строку, которую вы видели ранее. Если текущая строка уже была замечена, пропустите ее.
Что-то вроде следующего (непроверенного) кода может работать:
<?php // array to hold all "seen" lines $lines = array(); // open the csv file if (($handle = fopen("test.csv", "r")) !== false) { // read each line into an array while (($data = fgetcsv($handle, 8192, ",")) !== false) { // build a "line" from the parsed data $line = join(",", $data); // if the line has been seen, skip it if (isset($lines[$line])) continue; // save the line $lines[$line] = true; } fclose($handle); } // build the new content-data $contents = ''; foreach ($lines as $line => $bool) $contents .= $line . "\r\n"; // save it to a new file file_put_contents("test_unique.csv", $contents); ?>
Этот код использует fgetcsv()
и использует запятую в качестве разделителя столбцов (на основе данных образца в вашем вопросительном комментарии).
Хранение каждой строки, которая была замечена, как указано выше, обеспечит удаление всех повторяющихся строк в файле независимо от того, являются ли они или нет, они непосредственно следуют друг за другом или нет. Если они всегда будут поддерживать друг друга, более простой метод (и больше памяти) будет хранить только последнюю видимую строку, а затем сравнивать с текущей.
UPDATE (повторяющиеся строки через колонку SKU, а не полную строку)
На основе выборочных данных, представленных в комментарии, «дублированные строки» на самом деле не равны (хотя они похожи, они отличаются большим количеством столбцов). Сходство между ними можно связать с одной колонкой, sku
.
Ниже приведена расширенная версия вышеуказанного кода. Этот блок будет анализировать первую строку (список столбцов) файла CSV, чтобы определить, в каком столбце содержится код sku
. Оттуда он сохранит уникальный список кодов SKU, и если в текущей строке будет «новый» код, он будет записывать эту строку в новый «уникальный» файл, используя fputcsv()
:
<?php // array to hold all unique lines $lines = array(); // array to hold all unique SKU codes $skus = array(); // index of the `sku` column $skuIndex = -1; // open the "save-file" if (($saveHandle = fopen("test_unique.csv", "w")) !== false) { // open the csv file if (($readHandle = fopen("test.csv", "r")) !== false) { // read each line into an array while (($data = fgetcsv($readHandle, 8192, ",")) !== false) { if ($skuIndex == -1) { // we need to determine what column the "sku" is; this will identify // the "unique" rows foreach ($data as $index => $column) { if ($column == 'sku') { $skuIndex = $index; break; } } if ($skuIndex == -1) { echo "Couldn't determine the SKU-column."; die(); } // write this line to the file fputcsv($saveHandle, $data); } // if the sku has been seen, skip it if (isset($skus[$data[$skuIndex]])) continue; $skus[$data[$skuIndex]] = true; // write this line to the file fputcsv($saveHandle, $data); } fclose($readHandle); } fclose($saveHandle); } ?>
В целом, этот метод гораздо более дружелюбен к памяти, так как ему не нужно сохранять копию каждой строки в памяти (только коды SKU).