2010-09-15 10 views
1

Я собираю данные об использовании usb всех пользователей и конвертируем их в CSV-файлы, чтобы я мог экспортировать их в некоторую базу данных. Текст входного файла выглядит следующим образом: -Как преобразовать текстовый файл в csv с помощью AWK

USB History Dump 
by nabiy (c)2008 
(1) --- Kingston DataTraveler 130 USB Device 
instanceID: 0018F3D974B4A9C0E1760896&0 
ParentIdPrefix: 7&b62e00e&2 
Last Mounted As: \DosDevices\I: 
Driver:{4D36E967-E325-11CE-BFC1-08002BE10318}\0033 
Disk Stamp: 09/07/2010 15:07 
Volume Stamp: 09/07/2010 15:07 
(2) --- Kingston DataTraveler 2.0 USB Device 
instanceID: 001D0F1E35B25B8C1201011B&0 
ParentIdPrefix: 7&1f5848f3&0 
Driver:{4D36E967-E325-11CE-BFC1-08002BE10318}\0035 
Disk Stamp: 09/06/2010 15:18 
Volume Stamp: 09/06/2010 15:18 
(3) --- Maxtor OneTouch III USB Device 
instanceID: 044303E5&0 
ParentIdPrefix: 
Driver:{4D36E967-E325-11CE-BFC1-08002BE10318}\0032 
Disk Stamp: 09/10/2010 10:09 
Volume Stamp: 03/12/2010 10:42 

Как я могу разобрать этот файл, так что я могу получить в следующем формате:

hostname Devic_name instanceID ParentPrefix LastMountedAs Driver 
pcname kingston xxxx xxxxxxxxx xxxxxxxxxx xxxxxxxx 
pcname maxtor 0440xxx 4 d 367 08/07/2010 xxxxxxxx 
pcname kingston xxxxxxx xxxxxxx xxxxxxxxx xxxxxxxx 

Имя ПК будет взято из команды хоста.

Требуемый результат в формате CSV для базы данных с некоторым сценарием пакетной или awk. Любое предложение очень ценится.

+2

Формат вывода вы показываете не CSV. –

+0

Нужно ли это awk? Будет ли Perl в порядке? –

ответ

0

Использование Perl, это может быть обработан таким образом, создавая подлинные данные CSV:

use strict; 
use warnings; 

my @keys = ("Device_Name", "instanceID", "ParentIdPrefix", 
      "Last Mounted As", "Driver"); 

my %values =(); 
my $host = qx/hostname/; 
chomp $host; 

while (<>) 
{ 
    chomp; 
    next unless m/^\(\d+\) ---/ || m/^[\w ]+:/; 
    if (m/\(\d+\) --- (\w+)/) 
    { 
     dump_entry(\%values); 
     %values =(); 
     $values{Device_Name} = $1; 
    } 
    else 
    { 
     my($key,$value) = split /:/; 
     $value =~ s/^\s+//; 
     $value =~ s/\s+$//; 
     $values{$key} = $value if $value ne ""; 
    } 
} 
dump_entry(\%values); 

sub dump_entry 
{ 
    my($ref) = @_; 
    my(%values) = %$ref; 
    return if (scalar(keys %values) == 0); 
    print qq%"$host"%; 
    foreach my $key (@keys) 
    { 
     my $value = $values{$key} // "--none--"; 
     print qq%,"$value"%; 
    } 
    print "\n"; 
} 

Пример вывода из данного файла данных:

"yourpcname","Kingston","0018F3D974B4A9C0E1760896&0","7&b62e00e&2","\DosDevices\I","{4D36E967-E325-11CE-BFC1-08002BE10318}\0033" 
"yourpcname","Kingston","001D0F1E35B25B8C1201011B&0","7&1f5848f3&0","--none--","{4D36E967-E325-11CE-BFC1-08002BE10318}\0035" 
"yourpcname","Maxtor","044303E5&0","--none--","--none--","{4D36E967-E325-11CE-BFC1-08002BE10318}\0032" 

Обратите внимание, что данные представлены в порядке чтения, в отличие от выходных данных в вопросе.

0

Follwing старые традиции, вот версия AWK кода Джонатана :-)

cat tess |awk ' 
function cmd(E, A, this,v){ A[0]=0;while((E |getline v)>0)A[A[0]+=1]=v;A["RETURN_CODE"]=close(E);} 
# whatever cvs format you perfer. Here we used a traditional type, with 
# escape sequence when 0x22 or , is present. 
function cvs(s){gsub(",","\\,",s);gsub("\"","\\\"",s);return ((s)?"\""s"\"":"\"--none--\"");}; 
BEGIN{ 
    cmd("hostname",A);host=A[1]; 
    f=0; 
    n=0; 
    print "hostname Devic_name instanceID ParentPrefix LastMountedAs Driver ";# Header 
    while(1){ 
     while((getline r)>0){ 
      if(r~"^[(][0-9]*[)]"){n=1;break;} 
      if(r!~":")continue; 
      key = substr(r,match(r,"^[^:]*"),RLENGTH);sub("^:[ \t]*","",key); 
      match(r,"^[^:]*[:][ \t]*"); 
      value = substr(r,RSTART+RLENGTH);sub("[\t ]*$","",value); 
      A[key]=value; 
     } 
     if(f){ 
      print cvs(host)","cvs(A["devic_name"])","cvs(A["instanceID"])","cvs(A["ParentIdPrefix"])","cvs(A["Last Mounted As"])","cvs(A["Driver"]); 
      delete A; 
     } 
     if(!n)break; 
     if(n)n=0; 
     f=1; 
     sub("^[(][0-9]*[)][ \t]*---[ \t]*","",r); 
     sub("[ ]*USB Device[ ]*$","",r); 
     A["devic_name"] = r; 
     continue; 
    } 
}' 

Пример вывода в виде follwing

hostname Devic_name instanceID ParentPrefix LastMountedAs Driver 
"host","Kingston DataTraveler 130","0018F3D974B4A9C0E1760896&0","7&b62e00e&2","\DosDevices\I:","{4D36E967-E325-11CE-BFC1-08002BE10318}\0033" 
"host","Kingston DataTraveler 2.0","001D0F1E35B25B8C1201011B&0","7&1f5848f3&0","--none--","{4D36E967-E325-11CE-BFC1-08002BE10318}\0035" 
"host","Maxtor OneTouch III","044303E5&0","--none--","--none--","{4D36E967-E325-11CE-BFC1-08002BE10318}\0032" 
Смежные вопросы