2.4 格式化和输出8 r' c, b% I: n- ?* R0 x* r
我们开始关注PowerShell是怎样配置显示输出的。普通的,我们只能运行命令然后依赖系统配置来显示7 j% c+ O& }, _, x8 h
( s* E' @$ x# h7 |
结果。有时候我们用Format-Table和Format-List之类的的命令来对显式的外观作个普通向导,只是内容* E" o) a/ i9 p! |1 X
* X7 p% R4 Y% ?) [3 q
不是太详细。让我们对此进行挖掘和看它如何工作的。
) x5 H0 q/ @7 {; r" q1 tPowerShell是基于类的系统,使用类来决定事情是怎样显示的。无论如何,普通的对象不用知道怎样显
; @% `1 \8 U; X+ o J) h" E
3 k' B& }+ i; ^6 |示自己。PowerShell用包含格式化信息的各种类型对象的数据库处理这些。这是可扩展类系统的一部分8 Y/ V% i' [, u- O7 A
. A* t7 n" [2 k. L4 a4 K,也是整个系统的重要组件。这种可扩展类的系统充许PowerShell在已经存在的.NET对象中增加新的行* y# B6 T7 y, w0 p- t
9 I3 y5 _# W& W2 x" s4 W2 _为。默认的格式化数据库被存储进PowerShell的安装路径中,你可以用$PSHOME脚本变量来得到这个路
3 x$ i( A; O8 `& [9 t, @+ C* N4 u/ C5 b7 b- a7 |( F
径。这是一份文件的清单:
9 ]7 _+ y2 k$ h' v2 g4 dPS (1) > dir $PSHOME/*format* | ft name! w6 @7 `; R2 z: h' v7 V2 i: I
Name* C& f8 U& h# V1 v6 g2 t
----
# }# C. @' M: ^7 k, i. kCertificate.Format.ps1xml
! Q: J3 ?; G" b+ E" IDotNetTypes.Format.ps1xml
~0 u" u2 k% C" ?5 j/ L: ~4 X' mFileSystem.Format.ps1xml
! G/ g- E- a+ P( S6 SHelp.Format.ps1xml
' v9 r% }2 w/ A/ V8 s9 rPowerShellCore.Format.ps1xml- E" l; ]6 S! Q5 V, T; I0 U
PowerShellTrace.Format.ps1xml
6 _& k! l" ?, ~/ |Registry.format.ps1xml
8 H, [1 m1 Y) {& D: k你可以多多少少的配置包含了描述的类型事物.(读完本书剩下的部分后,其它的事物也变得清楚起来.)
6 X6 \% ]# L! e& A3 h. ?+ Q3 Y这些文件是包含了描述的XML文档,这些文档相当的复杂以至于很难写.最终用户有可能添加他们自己的类
* Q- Z: {2 A X k& u. P
9 k' v5 V& F3 ^; ^& }' p# e型描述,但这个举动超出了本篇的领域.这一篇中最重要的是理解怎样格式化和输出命令.
; r# M+ W/ y8 ~% k3 T1 _2.4.1 格式化的cmdlets
2 z+ I' C! ^- X; @6 i3 c& ~被对象类型控制的显示信息已经被显示出来,但是用户可以用"foruma-"命令选择符合的对象:# I* \( F# K- |/ M1 N, }" k B) k3 n; i
PS (5) > get-command format-* | ft name
: e" S8 |; M# Q( p0 Z! Y* T0 xName# B2 j5 w% D$ P+ y
----# _6 x0 f* M6 t- R& P1 e
Format-Custom
3 ?+ [! M- _* x! N1 {Format-List3 b) D0 F' o2 v0 O3 P
Format-Table
* Q J6 v# \0 v7 e# A* F6 n5 IFormat-Wide E' S: ^8 X+ G' V4 N t
形式上,事情就像一个表或清单.他们是这么工作的.format-table cmdlet把一系列的列通过屏幕显示了出来:
. d& r+ @4 U. ?5 ]. @$ IPS (1) > get-item c:\ | format-table
5 u' A6 D& X. m' s+ z3 _ Directory:
% {; @/ u+ k; e+ XMode LastWriteTime Length Name
% p1 z1 e7 w7 s---- ------------- ------ ----
% z) `4 d6 Q! B, z* o: W6 {d--hs 4/9/2006 10:04 PM C:\
/ E6 ~/ d5 Z P7 |. B2 \* z默认的,它试着使用最大的宽度来显示和猜测详细的字段是怎样的.这让你一开始就在最短时间内看到数& q+ U0 g* M; ?( d, ^0 @8 A! I
: n" v) {9 w/ M" q据.(流行为),但是并不会总是产生优化的结果.你可以用-autosize switch来得到一个好的显示结果,这样会需5 r2 R( o1 C/ K. V$ }
4 ] S0 f' }( U2 p要在显示他们前格式化每个元素的进程.在用每个字段时我们不得不配置好最好的宽度.这个例子的结果如
$ I c% W7 K% [" P1 F% U$ k% f( C( m1 Q% n% i, n9 q/ f
此:# m0 ?" [6 Z ~* y) @9 ^- k
PS (3) > get-item c:\ | format-table -autosize
4 g- A9 {2 F/ y9 p Directory:
' x/ h( h7 f$ \9 ]Mode LastWriteTime Length Name/ ^# k5 ~9 U) s' |8 [ A- ?
---- ------------- ------ ----8 q) M* t7 P) p; C
d--hs 4/9/2006 10:04 PM C:\
' Y7 }& n1 a0 EOkey----所以它看上去没多少不同:白空间把事情更压缩了.实际上,流默认的层相当的棒而且你不用使用" _* `2 D2 j6 ?) \" ?& b& e
. |- |, J/ P7 }+ T2 o
use-autosize,但是有时你可以利用这些提高事情的可读性.7 [6 d4 ]% U) o( C4 d5 v; c
format-list命令,再另一方面,下面用对象的一个清单显示了所有元素:
# V, L4 U3 T2 x) a% c4 ~PS (2) > get-item c:\ | format-list. ^/ H* g% w+ k; s- B' p( t# m
Directory:+ w8 l% v2 _. a
Name : C:\
+ F( i& j/ {& L2 t3 @CreationTime : 2/26/2001 3:38:39 PM
8 X& D$ `' V: V( ULastWriteTime : 4/9/2006 10:04:38 PM0 a9 [3 L d! o( x* F1 _
LastAccessTime : 4/11/2006 9:33:51 PM( @+ |6 s8 D( m7 K$ i$ O$ q
如果要显示多于一个的对象,将要显示一系列的清单.让我们用例子试试: b% Q& u7 K4 V1 D* M
PS (3) > get-item c:\,d:\ | fl
) a; X) M4 o! K5 b" D& P Directory:
K1 E a3 H1 u6 AName : C:\
/ A0 y. ]5 ?: ~- VCreationTime : 2/26/2001 3:38:39 PM0 X; r' \6 m- b ^
LastWriteTime : 6/21/2006 1:20:06 PM
: P! P/ r7 l5 A. Y# T) q1 R& nLastAccessTime : 6/21/2006 9:14:46 PM* ^7 [. ^7 ~5 e& a" `/ g, p
Name : D:\" r0 Y2 V. c. F% \/ {7 z" j- V, U5 A
CreationTime : 12/31/1979 11:00:00 PM
, ?' M6 f& r. v8 |! O* S: nLastWriteTime : 12/31/1979 11:00:00 PM3 C D" F! X5 G7 N& @9 S4 Q
LastAccessTime : 12/31/1979 11:00:00 PM0 \0 ^7 z a' c! `, n2 M+ v
最好的显示大量收集的字段的方法不适合全屏幕显示(显然-autosize交换方法对这种类型的输出不太适合)- y. x+ T" S( H9 U" Z
Format-Wide cmdlet在你想要使用一个简单的对象属性时使用一个简单的方法.屏幕在显示同样的信息时
, E( _, g/ i, Q将要把屏幕处理成一系列的列.比如这个例子:
" {4 M8 I6 `- I* D! Z; MPS (1) > gps s* | format-wide -Column 8 id
4 ~6 w2 Z' d8 ?1 T1372 640 516 1328 400 532 560 828
g5 a5 @9 K$ z( ^) L' b/ I876 984 1060 1124 4
4 n, |+ v( y, @- W7 }9 b' d这个例子中,我们将要用八列显示所有名字带"s"的所有进程的进程ID.这个处理机制充许密集的显示信息.
- e6 M7 n/ W1 a) i7 A! q& ^最后的处理机制是Format-Custom.这个显示对象将要保护对象的基础结构.更多的对象有一些结构包含其: M9 y1 o* n5 K' a" B9 p
- u9 J& p x7 l; {, k. }9 b; t
它对象,which,in turn,包含其它对象,这些可以产生极端冗长的输出.这是从Get-Item cmdlet的小部分的输出,
' `4 B% n( |- l' V9 v# @' ^用Format-Custom来显示:, s4 K" r6 v7 p& U1 Q3 L9 ~+ ^
PS (10) > get-item c:\ | format-custom -depth 13 |4 ]6 ]4 N# a
class DirectoryInfo" S% c% n/ n, `" V) P
{. r( V# Q1 m( ]3 v0 ]# z
PSPath = Microsoft.PowerShell.Core\FileSystem::C:\: K! B1 G3 C. I ^9 a5 [
PSParentPath =
/ b+ r4 k' U5 w" }/ L) {2 J PSChildName = C:\
9 B/ w+ g+ D$ P4 b0 R PSDrive =# K/ T2 \7 C+ b4 y2 D
class PSDriveInfo/ R6 u* F3 c6 ], Y3 i
{
4 X7 f! c+ X' Q' v' J CurrentLocation =
' m9 [1 v! o! S Name = C# h( X0 Z) b0 Y( `
Provider = Microsoft.PowerShell.Core\FileSystem2 O6 |) r( w. S1 D! ~% `
Root = C:\
; F& \, {. q2 b, Y5 y' ?7 d! e Description = C_Drive! A$ K" ?0 T% t% y6 p+ P& w. M
Credential = System.Management.Automation.PSCredential
1 e* @* d3 q/ P% p+ I# B6 O* ` }1 R) ?, m6 V* U8 x; s# `% N, C
全部的输出非常的长,需要注意的是,我们说它在depth 1处停止运行.你可以设想,这个输出结果是多么冗余
' |; b/ J- M& c [' @" E2 b6 Z q* r- P8 I! h- L% @4 r# ?! z1 h7 g9 H3 S
了!但是,为什么有这个cmdlet呢?因为它是有用的debugging tools,在你建立自己的对象或者仅仅探索.NET$ s3 o9 D. {2 ^7 _* _& ?- T
9 }9 o( r0 c5 h# r& Q. _/ W- ?类库中存在的对象时.你会发现,这是一个在当机时有脏对象时保存你后面的容器的方法.(脏,可以认为已经
* j3 K+ V9 ^# J, d" \' ]
2 I4 q$ T+ Y" d* n! j& l% q有修改但未进行提交的数据,当机时,这种数据应该是即时性的最宝贵的数据.但是脏对象嘛,大家可以讨论,
+ c0 v+ C& E- y3 Z6 u/ m
( Y1 F- ? ~* e9 [1 H7 y8 F0 w1 e下面的部分有谈到这个时,我会回来更正的.),而不仅仅作普通的每日性的基础工作.