2016-04-26 4 views
-1

私は自分がやりたいことをする方法を理解するためにインターネットをトロールしてきましたが、無駄です。私は...このように、テーブルレイアウトにbashBashの行を転置する

Caption Description  DriveType FreeSpace  ProviderName Size   VolumeName 
C:  Local Fixed Disk 3   41265664000     146056146944  
D:  Local Fixed Disk 3   125067259904     1073738674176 Data 
E:  Removable Disk  2 

Caption=C: 
Description=Local Fixed Disk 
DriveType=3 
FreeSpace=41265664000 
ProviderName= 
Size=146056146944 
VolumeName= 
Caption=D: 
Description=Local Fixed Disk 
DriveType=3 
FreeSpace=125067259904 
ProviderName= 
Size=1073738674176 
VolumeName=Data 
Caption=E: 
Description=Removable Disk 
DriveType=2 
FreeSpace= 
ProviderName= 
Size= 
VolumeName= 

....以下のデータを転置する必要があります。私はawkスクリプトの無数を探ってきましたが、私はそれらの背後にあるロジックをよく理解していないようです。

ご協力いただければ幸いです。ありがとうございました! gawk

+1

あなたが必要な理由ここで 'bash'、' sed'または 'awk'を使うのですか?これらの問題は、 'perl'や' python'を使って簡単に解決することができます。 – nowox

+0

'bash'、' sed'、 'awk'は始めたパスです。より良いツール/ソリューションがあれば、私はそのように喜んでいます。 –

答えて

1

awk -v RS="Caption" -F"[=\n\"]" ' 
    NR==2{ 
     printf RS; 
     for(i=3;i<=NF;i+=2){ 
      printf ":"$i 
     }; 
     print "" 
    }; 
    { 
    for(i=2;i<=NF;i+=2){ 
     if ($i != "") printf ":"$i; 
     else printf ": " 
    }; 
    print ""}' file | column -s":" -t 
1

あなたはこのようなPerlpythonとしてこれを行うには、他のツールを使用することができます。

Perlでは、たとえば、あなたがこれを使用することができます:

#!/usr/bin/perl -n 
use Text::ASCIITable; 

next unless /^(\w+)\s*=\s*(.*)$/; 
$data{$1} = [] if not $data{$1}; 
push $data{$1}, $2; 

END { 
    $t = Text::ASCIITable->new(); 
    $t->setCols(keys %data); 

    for my $i ([email protected]{$data{(keys %data)[0]}} - 1) { 
     $t->addRow(map $data{$_}[$i], keys %data) 
    } 
    print $t; 
} 

あなたのデータはdata.txtにすることができますので、書くことができます。

$ ./myscript.pl data.txt 
.---------------------------------------------------------------------------------------------------. 
| Caption | Size   | DriveType | VolumeName | FreeSpace | Description  | ProviderName | 
+---------+---------------+-----------+------------+--------------+------------------+--------------+ 
| C:  | 146056146944 |   3 |   | 41265664000 | Local Fixed Disk |    | 
| D:  | 1073738674176 |   3 | Data  | 125067259904 | Local Fixed Disk |    | 
| E:  |    |   2 |   |    | Removable Disk |    | 
'---------+---------------+-----------+------------+--------------+------------------+--------------' 

このスクリプトは、汎用的な列のN数について任意の順序で与えられる。あなたがしたい場合は、Pythonで

#!/usr/bin/perl -n 
use Text::ASCIITable; 

BEGIN { 
    @columns = qw/Caption Description DriveType FreeSpace ProviderName Size VolumeName/; 
    $t = Text::ASCIITable->new(); 
    $t->setCols(@columns); 
    $re = join "\n", map "$_=(?<$_>.*)", @columns; 
    undef $/; 
} 

$t->addRow(map $+{$_}, @columns) while(/$re/g); 

END { print $t; } 

あるいは:列が同じ順序で知られており、常に表示されている場合は、コードは次のように簡略化することができ

#!/usr/bin/python 
import sys 
from terminaltables import AsciiTable 
table_data = [] 
for row in ["Caption" + d for d in sys.stdin.read().split("Caption")[1:]]: 
    table_data.append([column.split('=')[1] for column in row.split("\n")[:-1]]) 
    columns = [column.split('=')[0] for column in row.split("\n")[:-1]] 

table_data.insert(0, columns) 
print AsciiTable(table_data).table 
0
$ cat tst.awk 
BEGIN { FS=OFS="=" } 
{ hdr = hdr sep $1; data = data sep $2; sep=OFS } 
$1=="VolumeName" { if (!c++) print hdr; print data; data=sep="" } 

$ awk -f tst.awk file | column -s= -t 
Caption Description  DriveType FreeSpace  ProviderName Size   VolumeName 
C:  Local Fixed Disk 3   41265664000     146056146944 
D:  Local Fixed Disk 3   125067259904    1073738674176 Data 
E:  Removable Disk 2 
関連する問題