[英]Transposing Rows to Columns in Bash
我已经在互联网上拖网捕捞了如何去做我想做的事,但是徒劳无功。 我需要转置下面的数据...。
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=
像这样的表格布局...
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
bash
。 我一直在探索各种awk
脚本,但是我似乎不太了解它们背后的逻辑:|
任何帮助,将不胜感激。 谢谢!
与gawk
:
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
您可以使用其他工具来执行此操作,例如Perl
或python
。
例如,在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 (0..@{$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个列,此脚本是通用的。 但是,如果知道这些列并始终以相同的顺序显示它们,则可以将代码简化为:
#!/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; }
甚至可以使用Python:
#!/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
$ 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.