#perl
#perl
Вопрос:
У меня есть обновление в моем скрипте для форматирования файла и удаления лишней запятой на основе поля DOE J, в некоторых моих строках есть лишняя, а в некоторых нет. Я заставил это работать, но проблема, с которой я сейчас сталкиваюсь, заключается в том, что мне не хватает одной из моих запятых, и я не уверен, почему это происходит.
while(<IN>) {
my $line = $_;
$line =~ s/^(([^,] ,){13})([^,]*),*([^,]*)(,[^,] ,.*)$/1345/;
print OUT "$line";
}
ВВОД:
555555,Service Location,06/30,210,OD44000,07/01/2011,09/01/2000,09/04/2000,1,07/01/2000,04/18/2000,2000-06-23 00:00:00,2000-07-01 00:00:00,DOE, J,11950000,349000,200000000A,07/13/2000,2000-07-27 00:00:00,20010002000600CAA,8,1, ,6,Yes,,No,,No,01001,2800038000,**SUM**,0,400,38648.44,0,,,,,,,,,,,,,,,,,6018.32,0,0,0,0,,,6018.32,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0
555555,Service Location,06/30,210,OD44000,07/01/2011,09/01/2000,09/04/2000,1,07/01/2000,04/18/2000,2000-06-23 00:00:00,2000-07-01 00:00:00,DOE J,11950000,349000,200000000A,07/13/2000,2000-07-27 00:00:00,20010002000600CAA,8,1, ,6,Yes,,No,,No,01001,2800038000,**SUM**,0,400,38648.44,0,,,,,,,,,,,,,,,,,6018.32,0,0,0,0,,,6018.32,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0
ВЫВОД:
555555,Service Location,06/30,210,OD44000,07/01/2011,09/01/2000,09/04/2000,1,07/01/2000,04/18/2000,2000-06-23 00:00:00,2000-07-01 00:00:00,DOE J,11950000,349000,200000000A,07/13/2000,2000-07-27 00:00:00,20010002000600CAA,8,1, ,6,Yes,,No,,No,01001,2800038000,**SUM**,0,400,38648.44,0,,,,,,,,,,,,,,,,,6018.32,0,0,0,0,,,6018.32,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0
555555,Service Location,06/30,210,OD44000,07/01/2011,09/01/2000,09/04/2000,1,07/01/2000,04/18/2000,2000-06-23 00:00:00,2000-07-01 00:00:00,DOE J11950000,349000,200000000A,07/13/2000,2000-07-27 00:00:00,20010002000600CAA,8,1, ,6,Yes,,No,,No,01001,2800038000,**SUM**,0,400,38648.44,0,,,,,,,,,,,,,,,,,6018.32,0,0,0,0,,,6018.32,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0
Ожидаемый результат:
555555,Service Location,06/30,210,OD44000,07/01/2011,09/01/2000,09/04/2000,1,07/01/2000,04/18/2000,2000-06-23 00:00:00,2000-07-01 00:00:00,DOE J,11950000,349000,200000000A,07/13/2000,2000-07-27 00:00:00,20010002000600CAA,8,1, ,6,Yes,,No,,No,01001,2800038000,**SUM**,0,400,38648.44,0,,,,,,,,,,,,,,,,,6018.32,0,0,0,0,,,6018.32,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0
555555,Service Location,06/30,210,OD44000,07/01/2011,09/01/2000,09/04/2000,1,07/01/2000,04/18/2000,2000-06-23 00:00:00,2000-07-01 00:00:00,DOE J,11950000,349000,200000000A,07/13/2000,2000-07-27 00:00:00,20010002000600CAA,8,1, ,6,Yes,,No,,No,01001,2800038000,**SUM**,0,400,38648.44,0,,,,,,,,,,,,,,,,,6018.32,0,0,0,0,,,6018.32,0,0,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0
Комментарии:
1. Все это
*
, одно за другим, довольно неприятно отслеживать в уме; они позволяют сопоставлять некоторые довольно неожиданные шаблоны. Можете ли вы объяснить словами, как предполагается проводить различие междуDOE, J, ...
иDOE J, ...
? (Оба они содержат строки, за которыми следуют запятые.) Я не могу понять из вашего кода, как он должен отличать их друг от друга. (DOE,J
Нужно исправить, верно?)2. ( Это всегда строки
DOE
иJ
? Я предполагаю, что вместо этого могут быть другие слова. Всегда ли речь идет о полях 13-и, возможно, 14, в виде текста с цифрами в полях прямо перед и после них? Фиксировано ли общее количество полей во всей строке? и т.д. …)3. Проблема здесь, похоже, в ваших входных данных. Он пытается разделяться запятыми, но затем он помещает случайную запятую внутри поля. Можете ли вы исправить это, чтобы любые текстовые поля, которые могут содержать запятые, заключались в кавычки? Таким образом, вы можете использовать что-то вроде Text::CSV_XS для анализа данных.
4. Каждая часть скобок является заполнителем для того, что делается, поэтому часть, в которой нет скобки, — это значение, которое я ищу и хочу исключить, то есть лишняя запятая в имени. Там после этого будут расположены поля без запятой и поля с запятой после этого. Решение, которое я нашел, состояло в том, чтобы указать, сколько еще запятых осталось после этого, и скопировать поля без запятой и поля с запятой.
Ответ №1:
В итоге я обратился к старому коллеге, и это то, что он предложил, и это сработало. В моем файле у меня количество запятых равно 90 после имени, поэтому я указал, что этот шаблон повторяется 90 раз после этого.
while(<IN>) {
my $line = $_;
$line =~ s/^(([^,]*,){13})([^,]*),*([^,]*)((,[^,]*){90})/1345/;
print OUT "$line";
}