Друзья:
Я должен обработать файл CSV, используя язык Perl, и создать Excel в качестве вывода, используя модуль Excel :: Writer :: XSLX. Это не домашнее задание, а реальная проблема, когда я не могу загрузить какую-либо Perl версию (на самом деле мне нужно использовать Perl 5.6) или какой-либо Perl модуль (у меня их ограниченный набор). Моя ОС UNIX. Я также могу использовать (встраивание в Perl) k sh и csh (с некоторыми ограничениями, как я обнаружил до сих пор). Пожалуйста, ограничьте ваши ответы доступными мне инструментами. Заранее спасибо!
Несмотря на то, что я не Perl разработчик, но из других языков я уже сделал свою работу. Однако заказчик требует дополнительной обработки, в которой я застреваю.
1) Камни на дороге, которую я обнаружил, поступают с двух сторон: из Perl и из Excel в конкретных стилях обработки данных. Я уже нашел обходной путь для работы с Excel, но - как уже упоминалось в теме - у меня возникают трудности при обработке нулей, найденных во входном файле CSV. Для работы с Excel я использую способ '0
, который является последним способом представления данных, который, как представляется, Excel при использовании стиля форматирования @
.
2) Сценарий:
Мне нужно отловить отдельные нули, которые могут присутствовать в любой строке / столбце / ячейке входного файла CSV, и поместить их как таковые (нули) в выходной файл Excel.
Я получу go напрямую на мой вопрос, чтобы не потерять ваше драгоценное время. После моего вопроса я предоставляю более подробную информацию:
Исследование и вопрос:
- Я пытался использовать регулярное выражение Perl, чтобы найти автономное "0" и заменить их любой строкой, планируя заменить их обратно на «0» в конце обработки.
perl -p -i -e 's/\b0\b/string/g' myfile.csv`
и
perl -i -ple 's/\b0\b/string/g' myfile.csv
Работают; но только из командной строки. Они не работают, когда я вызываю их из сценария Perl следующим образом:
system("perl -i -ple 's/\b0\b/string/g' myfile.csv")
Не знаю почему ... Я уже пытался использовать exec
и eval
вместо system
, с теми же результатами.
Обратите внимание, что у меня есть тонна регулярных выражений, которые прекрасно работают с такой же структурой, например:
system("perl -i -ple 's/input/output/g' myfile.csv")
Я также пытался использовать обратные ссылки и qx//
, без успеха. Обратите внимание, что qx//
и обратные пометки имеют не одинаковое поведение, так как qx//
жалуется на границы \ b из-за прямого слэ sh.
Я пытался использовать sed -i
, но моя система отклоняет -i
как недопустимый флаг (не знаю, происходит ли это во всех UNIX, но, по крайней мере, это происходит в рабочем состоянии. Однако принимает perl -i
).
Я пробовал встраивать awk
(который работает из командной строки), таким образом:
system `awk -F ',' -v OFS=',' '$1 == \"0\" { $1 = "string" }1' myfile.csv > myfile_copy.csv
Но это работает только для первого столбца (в командной строке) и, кроме недостатка наличия дополнительного файла копии, Perl жалуется на перенаправление >
, предполагая, что оно "больше чем" ...
system(q@awk 'BEGIN{FS=OFS=",";split("1 2 3 4 5",A," ") } { for(i in A)sub(0,"string",$A[i] ) }1' myfile.csv@);
Это awk
работает из командной строки, но только 5 столбцов. Но не в Perl с использованием @
.
Все комбинации exec
и eval
также были протестированы безуспешно.
Я также пытался перейти на system
каждый из awk
компонентов, в качестве аргументов, разделенных запятыми, но не нашел какого-либо действительного способа передать редиректор (>
), поскольку Perl отклоняет его по указанной причине.
Используя другой подход, я заметил, что «автономные нули» кажутся «проглоченными» модулем Text :: CSV, таким образом, я избавился от него и вернулся к традиционному циклу в csv строка за строкой и разделитель запятых, сохраняя нули таким образом. Однако я обнаружил «тайну» isdual
в Perl, и из-за ограниченности имеющихся у меня модулей я не могу использовать Dumper
. Затем я также исследовал возможности двоичных файлов в Perl и попробовал $x ^ $x
, который устарел с версии 5.22, но действителен до этой версии (я сказал, что у меня 5.6). Это полезно, чтобы ловить числа против строк. Однако, в то время как if( $x ^ $x )
возвращает TRUE
для строк, if( !( $x ^ $x ) )
не возвращает TRUE
при $x = 0
. [ОБНОВЛЕНИЕ: Я попробовал это в выделенном Perl сценарии, просто для этой цели, и он работает. Я считаю, что мое вероятное неправильное заключение («не возвращать ИСТИНА») было получено, когда я все еще не осознавал, что Text :: CSV поглощал мои нули. Выполняю новые тесты ...].
Я буду очень признателен за вашу помощь!
БОЛЬШЕ ДЕТАЛЕЙ ПО МОИМ ТРЕБОВАНИЯМ:
1) Это динамический отчет c, поступающий из базы данных, который передается мне, и я программно забираю из папки. Dynami c означает, что в нем может быть любое количество таблиц, какое количество столбцов в каждой таблице, какие имена называются заголовками столбцов, какое количество строк в каждой таблице.
2) Я не знаю, и не может знать, имена столбцов, потому что они варьируются от отчета к отчету. Поэтому я не могу ориентироваться на имена столбцов.
Пример ввода:
Alfa,Alfa1,Beta,Gamma,Delta,Delta1,Epsilon,Dseta,Heta,Zeta,Iota,Kappa
0,J5,alfa,0,111.33,124.45,0,0,456.85,234.56,798.43,330000.00
M1,0,X888,ZZ,222.44,111.33,12.24,45.67,0,234.56,0,975.33
3) Ввод Объяснение
a) Это пример случайного отчета с 12 столбцов и 3 ряда. Первая строка - это заголовок.
b) Я называю "автономные нули" теми "чистыми" нулями, которые появляются в файле CSV, начиная со второй строки, между запятыми, как 0,
(если это случай первая позиция в строке) или как ,0,
в последующих позициях.
c) Во второй строке примера вы можете прочитать, с начала строки: 0,J5,alfa,0
, что в этом Частным случаем являются «слова» или «строки». В этом случае 4 имени (обратите внимание, что два из них являются нулями, которые должны рассматриваться как строки ). Таким образом, у нас есть пример с 4 именами столбцов (Alfa,Alfa1,Beta,Gamma
- заголовки для этих столбцов, но только в этом сценарии). Начиная с этой точки, во втором ряду вы можете видеть числа с плавающей запятой (* .00) и среди них вы можете видеть 2 нуля, которые являются числами . Наконец, в третьей строке вы можете прочитать M1,0,X888,Z
, которые являются именами для первых 4 столбцов. Обратите внимание, что в 4-м столбце второй строки в качестве имени указано 0
, а в 4-м столбце третьей строки - в качестве имени ZZ
.
Сводка. Таблица-отчет разделена на 2 части, слева направо: 4 столбца для имен и 8 столбцов для чисел. Всегда первые M столбцов являются именами, а последние N столбцов являются числами. - Неизвестно, какое число равно М: какое количество столбцов, выделенных для слов / строк, я получу. - Неизвестно, какое число N: какое количество столбцов, посвященных номерам, я получу. - ИЗВЕСТНО, что после того, как количество столбцов M заканчивается, всегда начинается N, и это постоянно для всех строк.