Perl : Как прочитать строки файла(CSV-файл) в хэш-ключи и отсортировать их в порядке возрастания, а затем записать их в новый отсортированный CSV-файл

#csv #sorting #perl #hash

Вопрос:

Итак, я обрабатываю этот CSV-файл, но проблема в том, что CSV-файл, похоже, сортируется по первому столбцу для каждой возвращаемой строки, но не на основе каких-либо других столбцов в той же строке.Я хочу отсортировать это в порядке возрастания строка за строкой, а не только по первому столбцу, чтобы несколько нормализовать их.

Содержимое CSV-файла выглядит следующим образом (вы можете скачать csv-файл отсюда https://www4.palmettogba.com/pdac_dmecs/searchProductClassificationResults.do?manufacturer=amp;codeDecision=amp;productName=amp;modelNumber=amp;classification=Surgical Dressings) введите описание изображения здесь

Я имею в виду следующее: считывать строки файла(CSV-файл) в хэш-ключи и сортировать их в порядке возрастания, а затем записывать их в новый отсортированный CSV-файл. но у меня нет навыков, чтобы сделать это на perl, мне действительно нужно сделать это на perl, так как я создаю скрипт для преобразования csv-файла в tsv, а затем в HTML, но сначала я хочу отсортировать csv-файл, прежде чем я его обработаю.

я имею в виду чтение строк файла в хэш-ключ $HASH($line_contents) =1; Сортировка хэш-ключей (для каждого моего $oneline (сортировка ключей %ХЭША)) При циклическом просмотре отсортированных ключей запишите ключи в новый отсортированный CSV-файл.

 #CHECK IF CSV FILE DOWNLOAD IS FINISHED
my $complete_download_flag = 0;

while($complete_download_flag == 0)
{
    my @download_directory = read_dir($download_dir_link);
    foreach my $downloaded_file (@download_directory)
    {
        if($downloaded_file =~ /QProduct Classification List.csvE/sgi)
        {
            $complete_download_flag = 1;
        }
    }
    sleep(5);
}
#SORTED CONTENTS OF CSV BEFORE CONVERSION function to put here
print "sORTING csv content...n";

#CONVERT CSV TO TSV
print "Converting csv to tsv...n";
my $csv = Text::CSV->new ({ binary => 1 });
my $tsv = Text::CSV->new ({ binary => 1, sep_char => "t", eol => "n"});

open my $infh,  "<:encoding(utf8)", "$download_dir_link/Product Classification List.csv";
open my $outfh, ">:encoding(utf8)", "Product Classification List.tsv";

while (my $row = $csv->getline ($infh))
{
    $tsv->print ($outfh, $row);
}
close($infh);
close($outfh);

my $tsv_content = "";
open(my $fh, '<', "Product Classification List.tsv");
while (<$fh>)
{
    $tsv_content = $tsv_content.$_;
}
close($fh);
print "Conversion complete! cleaning tsv content...n";
 

Комментарии:

1. Возможно Text::CSV , это может помочь

2. «я имею в виду чтение строк файла в хэш-ключ $HASH($line_contents) =1; Сортировка хэш-ключей (для каждого моего $oneline (сортировка ключей %ХЭША)) При циклическом просмотре отсортированных ключей запишите ключи в новый отсортированный CSV-файл» Звучит для меня хорошо.

3. При использовании хэш-ключей вы рискуете перезаписать данные, если ключи идентичны. Я не думаю, что это было бы вам приятно. Вам не нужен хэш для сортировки csv.

Ответ №1:

(Во-первых, когда я экспортировал данные в формате CSV по вашей ссылке, в сохраненном файле вверху было несколько дополнительных строк; все, что следует ниже, предполагает, что вы их удалили.)

Ряд подходов:

Поскольку это похоже на простой CSV-файл без многострочных записей, просто отсортируйте его с помощью стандартной sort(1) утилиты либо перед обработкой файла в perl:

 $ (head -1 "Product Classification List.csv"; sed "1d" "Product Classification List.csv" | sort) > sorted.csv
 

Или, используя часто удобный Text::AutoCSV для преобразования из CSV в TSV и сортировки всего perl (это тоже можно легко адаптировать к однострочному):

 #!/usr/bin/env perl
use warnings;
use strict;
use Text::AutoCSV;

# Original CSV file and output TSV file are command-line arguments, not
# hard-coded.

Text::AutoCSV->new(in_file => $ARGV[0], encoding => "UTF-8", out_file
                   => $ARGV[1], out_sep_char => "t", out_orderby => [
                   "PRODUCTNAME", "MANUFACTURERDISTRIBUTOR",
                   "MODELNUMBER"," HCPCSCODE", "EFFECTIVEBEGINDATE",
                   "EFFECTIVEENDDATE", "COMMENTS" ])->write;
 

Или используйте csvkit из командной строки для сортировки и преобразования:

 $ csvsort "Product Classification List.csv" | csvformat -T > sorted.tsv
 

Комментарии:

1. У меня действительно есть вопрос, Шон, мне нужна функция, которую нужно вставить, прежде чем я конвертирую CSV-файл в TSV, а затем в HTML-файл, приведенное выше предложение работает, но не в моем случае, я думаю ? Скрипт , который я сделал , очищает веб-сайт(ссылка на файл CSV) на этом веб-сайте есть сотня файлов CSV , я разобрал их функцию для них, моя единственная проблема в том, что вывод, который я получаю, не упорядочен в формате по возрастанию, он несколько испорчен, он отсортирован только по первому столбцу, поэтому мне нужно, чтобы перед преобразованием CSV в TSV я хотел, чтобы CSV был отсортирован в формате по возрастанию.

2. до того, как я обработал его в TSV. У вас есть идеи о том, как это сделать ? Спасибо

3. Как вы также заметили, CSV с веб-сайта не упорядочен по возрастанию, он каким-то образом динамически сортируется только по первому столбцу .

4. @johndenverabella Да, и все это в своем роде.

5. (И два из них преобразуются в TSV. Вместо одного сценария, который делает все, разбейте его на более мелкие этапы и соедините их все вместе).