#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. Вместо одного сценария, который делает все, разбейте его на более мелкие этапы и соедините их все вместе).