String 获取内容的真正输出是一个字符串还是几个属性?

String 获取内容的真正输出是一个字符串还是几个属性?,string,powershell,String,Powershell,获取内容的真正输出是什么,字符串还是具有多个属性的对象?如果是对象,哪个属性包含字符串,我可以修改该属性吗?该文件只有一行,因此我不必处理对象数组 PS C:\Users\me> Get-Content input.txt 111 PS C:\Users\me> Get-Content input.txt | Select-Object * PSPath : C:\Users\me\input.txt PSParentPath : C:\Users\me PSChildName

获取内容
的真正输出是什么,字符串还是具有多个属性的对象?如果是对象,哪个属性包含字符串,我可以修改该属性吗?该文件只有一行,因此我不必处理对象数组

PS C:\Users\me> Get-Content input.txt 111 PS C:\Users\me> Get-Content input.txt | Select-Object * PSPath : C:\Users\me\input.txt PSParentPath : C:\Users\me PSChildName : input PSDrive : C PSProvider : Microsoft.PowerShell.Core\FileSystem ReadCount : 1 Length : 3 PS C:\Users\me> (Get-Content input.txt).GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True String System.Object
不带
-Raw
开关的
Get-Content
cmdlet返回一个字符串数组,该数组包含文本文件的所有行,按换行符拆分。 使用带有
-Raw
开关的
Get Content
,以单个字符串的形式返回文件内容,包括换行符

话虽如此,如果(如您的情况)文本文件仅包含一行,PowerShell将自动“取消装箱”返回的数组并返回单个字符串

NET中的字符串是对象,具有属性和方法。 请尝试
“abc”|获取成员
,查看有关字符串对象的其他内容

如果执行“abc”|选择对象*,则输出将为

PowerShell现在只显示字符串的
Length
属性

Get Content
但是,向已注释的结果(字符串)对象添加额外信息,这些信息都与文件本身有关。(
PSPath、PSParentPath、PSChildName、PSDrive、PSProvider、ReadCount
)。这些额外属性都以
NoteProperty
的形式添加,如果添加,您可以看到它们已添加

(Get-Content input.txt) | Get-Member
这将返回一个令人印象深刻的列表,但对象仍然是类型

当您使用
(Get Content input.txt)-replace 111222
对该字符串执行
-replace
操作时,结果将是新的字符串对象,不再具有额外的文件相关属性。现在它只是一个字符串,因此与它最初的来源无关

希望这能解释

  • 获取内容
    输出.NET
    [string]
    对象的数组[1],每个对象表示输入文件中的一行。

  • 但是,
    Get Content
    还使用其他属性装饰这些字符串对象,这些属性提供有关字符串来源的有用元数据。

  • 所有数据检索cmdlet-
    获取子项
    获取项
    获取内容
    ,…-这样做;具体来说,它们使用以下
    NoteProperty
    成员装饰输出对象:
    PSPath
    PSParentPath
    PSChildName
    PSDrive
    PSProvider

  • 这种装饰是由特定于PowerShell的(主要是)不可见的帮助器类型,
    [psobject]
    实现的,其中.NET对象被包装,并且可以存储其他属性

  • 通常,修饰的.NET对象的行为与正常情况相同;e、 例如,输出由
    Get Content
    返回的字符串将按原样打印它们,而不表示它们现在包含其他属性(从PowerShell的角度来看)

  • 但是,当涉及到序列化,或使用
    选择对象*
    克隆对象,或使用反射(属性枚举)的其他上下文时,这些属性确实很重要,并且确实会出现,如您的问题所示

    • 例如,当您使用
      converttojson
      进行序列化时,PowerShell还会序列化其他属性,并且(有些人为地)将字符串的内容表示为伪属性
      ——请参阅

    • 在修饰的
      [string]
      实例上访问
      .psobject.BaseObject
      ——仅[2]——允许您根据需要绕过PowerShell添加的属性,只返回底层的.NET
      [string]
      实例(基本对象)

  • 由提供程序cmdlet(如
    Get Content
    )添加的
    NoteProperty
    成员是实例成员,即它们特定于给定对象。(PowerShell还允许您在类型级别装饰对象)

    • 因此,当您构造一个新的
      [string]
      实例时,例如通过使用
      -replace
      操作符(或者,通常,任何返回新字符串的字符串操作),新实例不具有附加属性

    • 从字符串操作的角度来看,即使是修饰的字符串也只是一个字符串;添加的属性在此上下文中不相关。此模式通常适用:装饰对象始终可以像其.NET基础对象一样工作,并且在大多数上下文中确实如此


[1] 严格地说,
Get Content
,就像任何cmdlet一样,对其输出对象进行流式处理,也就是说,它将它们一个接一个地发送到管道中。只有在捕获此输出时(例如通过分配给变量),才是按需构造的数组(
[object[]]
),假设输入文件包含两行或多行-否则,唯一一行作为自身捕获,而不是包装在数组中-有关详细信息,请参阅

[2] 在PowerShell版本3及更高版本中,实例ETS成员不再与给定的.NET基本对象的
[psobject]
包装器关联,而是与基本对象本身关联,使用所谓的恢复表
[string]
实例是唯一的例外,出于技术原因,这就是为什么只有使用
[string]
实例才能使用
.psobject.BaseObject
真正获得未修饰的对象-对于所有其他类型,访问基本对象实际上是不可操作的,因为返回的对象仍然会显示实例成员(也是)。
但是,
.psobject.BaseObject
仍然可以用于访问基本对象的成员(属性、方法),以防这些成员被
Length
------
     3
(Get-Content input.txt) | Get-Member