Как удалить непечатаемый символ ^ @ в perl - PullRequest
3 голосов
/ 18 июня 2020

У меня есть простой perl скрипт, как показано ниже

use strict; 
use warnings 'all';
use Text::CSV;
use open ":std", ":encoding(UTF-8)";
my $in_file = $ARGV[0] or die "Usage: $0 filename\n";
my $out_file = $ARGV[1] or die "Usage: $0 filename\n";
my $csv = Text::CSV->new( { binary => 1, auto_diag => 1 }); 
my $out_csv = Text::CSV->new ( { binary => 1, 
                auto_diag => 1, 
                eol => $/,
                    sep_char => ',', 
                quote_char => '"', 
                always_quote => 1});
open my $data,   '<:encoding(UTF-8)', $in_file or die $!; 
open my $fh_out, '>:encoding(UTF-8)', $out_file or die $!; 

while (my $words = $csv->getline($data))  
{ 
    tr/\r\n//d for @$words;
    tr/,/;/ for @$words;
    tr/"/'/ for @$words;
    $out_csv->print($fh_out, $words);
} 

Все, что он делает, это в основном конвертирует файл csv в более структурированный, что легко понять внешнему приложению, имеющему ограничения. Скрипт удаляет ненужную новую строку, запятые и двойные кавычки, которые вводятся как часть пользовательского текста. Это хорошо работает. Однако недавно в одном из входных файлов у нас есть непечатаемый символ ^ @, скрипт не дает сбоев, но в выходном файле есть дополнительные символы "0

Не уверен, что могу привести пример входного файла. так как charcater не печатается. См. вывод команды ниже.

cat Input.csv 
ObjectId,OrgId,Title,ObjectType,Type,ObjectId,Location,StartDate,EndDate,DueDate,ObjectId1,ObjectId2,ObjectId3,LastModified,IsDeleted,SortOrder,Depth,DummyId,IsHidden,ResultId,DeletedDate,CreatedBy,LastModifiedBy,DeletedBy
3386484,532947,Test,Topic,Auto,3386415,http://www.test.com ,,,,,,,2016-06-27T05:08:26.3070000Z,1,443,3,,False,,2017-02-16T00:31:39.4870000Z,,,

С параметром cat -e вы можете увидеть непечатаемый символ.

cat -e Input.csv 
M-oM-;M-?ObjectId,OrgId,Title,ObjectType,Type,ObjectId,Location,StartDate,EndDate,DueDate,ObjectId1,ObjectId2,ObjectId3,LastModified,IsDeleted,SortOrder,Depth,DummyId,IsHidden,ResultId,DeletedDate,CreatedBy,LastModifiedBy,DeletedBy^M$
3386484,532947,Test,Topic,Auto,3386415,http://www.test.com ^@,,,,,,,2016-06-27T05:08:26.3070000Z,1,443,3,,False,,2017-02-16T00:31:39.4870000Z,,,^M$

После того, как файл будет отправлен через сценарий вывод выглядит следующим образом. С дополнительным «0 в конце http://www.test.com

cat -e Output.csv 
"M-oM-;M-?ObjectId","OrgId","Title","ObjectType","Type","ObjectId","Location","StartDate","EndDate","DueDate","ObjectId1","ObjectId2","ObjectId3","LastModified","IsDeleted","SortOrder","Depth","DummyId","IsHidden","ResultId","DeletedDate","CreatedBy","LastModifiedBy","DeletedBy"$
"3386484","532947","Test","Topic","Auto","3386415","http://www.test.com "0","","","","","","","2016-06-27T05:08:26.3070000Z","1","443","3","","False","","2017-02-16T00:31:39.4870000Z","","",""$

Добавление вывода команды согласно запросу Дейва

od - ch Input.csv

0000000 357 273 277   O   b   j   e   c   t   I   d   ,   O   r   g   I
           bbef    4fbf    6a62    6365    4974    2c64    724f    4967
0000020   d   ,   T   i   t   l   e   ,   O   b   j   e   c   t   T   y
           2c64    6954    6c74    2c65    624f    656a    7463    7954
0000040   p   e   ,   T   y   p   e   ,   O   b   j   e   c   t   I   d
           6570    542c    7079    2c65    624f    656a    7463    6449
0000060   ,   L   o   c   a   t   i   o   n   ,   S   t   a   r   t   D
           4c2c    636f    7461    6f69    2c6e    7453    7261    4474
0000100   a   t   e   ,   E   n   d   D   a   t   e   ,   D   u   e   D
           7461    2c65    6e45    4464    7461    2c65    7544    4465
0000120   a   t   e   ,   O   b   j   e   c   t   I   d   1   ,   O   b
           7461    2c65    624f    656a    7463    6449    2c31    624f
0000140   j   e   c   t   I   d   2   ,   O   b   j   e   c   t   I   d
           656a    7463    6449    2c32    624f    656a    7463    6449
0000160   3   ,   L   a   s   t   M   o   d   i   f   i   e   d   ,   I
           2c33    614c    7473    6f4d    6964    6966    6465    492c
0000200   s   D   e   l   e   t   e   d   ,   S   o   r   t   O   r   d
           4473    6c65    7465    6465    532c    726f    4f74    6472
0000220   e   r   ,   D   e   p   t   h   ,   D   u   m   m   y   I   d
           7265    442c    7065    6874    442c    6d75    796d    6449
0000240   ,   I   s   H   i   d   d   e   n   ,   R   e   s   u   l   t
           492c    4873    6469    6564    2c6e    6552    7573    746c
0000260   I   d   ,   D   e   l   e   t   e   d   D   a   t   e   ,   C
           6449    442c    6c65    7465    6465    6144    6574    432c
0000300   r   e   a   t   e   d   B   y   ,   L   a   s   t   M   o   d
           6572    7461    6465    7942    4c2c    7361    4d74    646f
0000320   i   f   i   e   d   B   y   ,   D   e   l   e   t   e   d   B
           6669    6569    4264    2c79    6544    656c    6574    4264
0000340   y  \r  \n   3   3   8   6   4   8   4   ,   5   3   2   9   4
           0d79    330a    3833    3436    3438    352c    3233    3439
0000360   7   ,   T   e   s   t   ,   T   o   p   i   c   ,   A   u   t
           2c37    6554    7473    542c    706f    6369    412c    7475
0000400   o   ,   3   3   8   6   4   1   5   ,   h   t   t   p   :   /
           2c6f    3333    3638    3134    2c35    7468    7074    2f3a
0000420   /   w   w   w   .   t   e   s   t   .   c   o   m      \0   ,
           772f    7777    742e    7365    2e74    6f63    206d    2c00
0000440   ,   ,   ,   ,   ,   ,   2   0   1   6   -   0   6   -   2   7
           2c2c    2c2c    2c2c    3032    3631    302d    2d36    3732
0000460   T   0   5   :   0   8   :   2   6   .   3   0   7   0   0   0
           3054    3a35    3830    323a    2e36    3033    3037    3030
0000500   0   Z   ,   1   ,   4   4   3   ,   3   ,   ,   F   a   l   s
           5a30    312c    342c    3334    332c    2c2c    6146    736c
0000520   e   ,   ,   2   0   1   7   -   0   2   -   1   6   T   0   0
           2c65    322c    3130    2d37    3230    312d    5436    3030
0000540   :   3   1   :   3   9   .   4   8   7   0   0   0   0   Z   ,
           333a    3a31    3933    342e    3738    3030    3030    2c5a
0000560   ,   ,  \r  \n
           2c2c    0a0d
0000564

Как я могу справиться с этим в скрипте, мне не нужен дополнительный "0 в выходном CSV.

Спасибо

Ответы [ 3 ]

3 голосов
/ 18 июня 2020

Как только вы узнаете числовое значение этого символа, вы можете использовать \x{}, чтобы указать его по этому номеру кода:

s/\x{....}//g;

Например, если это символ ?, я могу найти его порядковый номер. Обычно я делаю это с помощью шестнадцатеричного дампа, но есть множество способов. Это U + 1F431:

s/\x{1F431}//g;

Вы также можете указать номер кода в восьмеричном формате для нешироких символов:

s/\200//g;

Или использовать их в диапазоне в классе символов:

s/[\200-\377]//g;
s/[\000-\037]//g;
s/[\000-\037\200-\377]//g;

Но, возможно, вы захотите сделать еще кое-что. Вы можете сопоставить его по свойству, которое у него есть (см. perluniprops ):

s/\p{XPosixCntrl}//g

Или с заглавной буквой P свойство, которого у него нет:

s/\P{Print}//g
0 голосов
/ 22 июня 2020

Я не уверен, как вы обнаружили, что это было ^ @, но вы должны иметь возможность ссылаться на любую такую ​​вещь, используя \ c @, где \ c означает «CTRL-». Итак, если бы это был SOH, \ x01, и вы видели, что он отображается как ^ A, вы можете указать s / \ cA // g, чтобы избавиться от него

0 голосов
/ 19 июня 2020

Итак, мы узнали две вещи из вашего шестнадцатеричного дампа файла:

  1. Это определенно файл UTF8, поскольку первые три символа - это маркер порядка байтов UTF8 (или BOM).
  2. Ваш символ проблемы c на самом деле является нулевым (с нулевым кодом).

Итак, следуя совету Брайана, вы сможете удалить символ с помощью:

s/\0//g;
...