如何通过powershell将每行文本文件保存为数组

问题描述 投票:2回答:2

如果我有一个文本文件,C:\ USER \ Documents \ Collections \ collection.txt具有以下信息:

collectionA.json
collectionB.json
collectionC.json
collectionD.json

我想知道如何通过Powershell,我能够将文本文件中的每一行存储为数组的元素,如...

array arrayFromFile = new Array;
foreach(line x in collection.txt)
{
    arrayFromFile.Add(x);
}

..最终目标是:

foreach(string x in arrayFromFile)
{
    newman run x;
}

我为这个看似简单的问题道歉 - 我以前从未处理过Powershell。

arrays powershell file-io line cmdlet
2个回答
8
投票

Get-Content命令将文本文件中的每一行作为单独的字符串返回,因此将为您提供一个数组(只要您不使用-Raw参数;这会导致所有行组合成一个字符串)。

[string[]]$arrayFromFile = Get-Content -Path 'C:\USER\Documents\Collections\collection.txt'

his excellent answer中,mklement0更详细地说明了当你调用这个命令时真正发生的事情,以及如果你担心性能而不是方便的替代方法。如果你有兴趣学习更多关于语言的知识而不仅仅是解决这个问题,那么绝对值得一读。


7
投票

补充JohnLBevan's helpful answer

Get-Content作为一个cmdlet,随着它们变得可用,将对象逐个输出到pipeline。 (请注意,即使没有管道符号|,也可以在调用cmdlet时涉及管道,用于链接多个命令)。 在这种情况下,输出对象是输入文本文件的各行。

如果收集管道的输出对象,例如将其分配给变量(如$arrayFromFile)或使用(...)的较大表达式上下文中的管道:

  • PowerShell在自动创建的数组中捕获多个输出对象,类型为[object[]]
  • 但是如果只有一个输出对象,则按原样捕获该对象(没有数组包装器)

为了确保管道的输出始终是一个数组,PowerShell提供了@(...), the array-subexpression operator,它甚至可以包装数组中的单个对象输出。

因此,PowerShell惯用解决方案是:

$arrayFromFile = @(Get-Content C:\USER\Documents\Collections\collection.txt)

但是,通常没有必要确保始终接收数组,因为PowerShell将标量(非集合的单个值)与许多上下文中的数组(集合)相同,例如在foreach语句中或输出时要枚举到管道的值。

TheMadTechnician指出你也可以使用[Array]来转换/类型约束管道输出作为@(...)的替代品,[object[]]也创建了# Equivalent of the command above that additionally locks in the variable date type. [Array] $arrayFromFile = Get-Content C:\USER\Documents\Collections\collection.txt 数组:

[Array] $arrayFromFile = ...

通过使用$arrayFromFile = [Array] (...)而不是$arrayFromFile,变量[Array]变为类型约束,这意味着它的数据类型被锁定(而默认情况下,PowerShell允许您随时更改变量的类型)。

[string[]]是John的答案[object[]]中使用的类型特定演员的独立命令替代品;你可以使用后者来强制在数组的元素中使用统一类型,但这在PowerShell [1]中通常是不必要的。

常规PowerShell数组的类型为$arrayFromFile,它允许混合不同类型的元素,但任何给定元素仍然具有特定类型;例如,即使上面命令之后的[object[]]的类型是$arrayFromFile[0][string]的类型,例如第一个元素,例如,$arrayFromFile[0].GetType().Name(假设文件包含至少1行;用[System.IO.File]验证类型)。


Faster alternative: direct use of the .NET framework

Cmdlet和管道提供高级,可能的内存限制功能,这些功能具有表现力和方便性,但它们可能很慢。

当性能很重要时,直接使用.NET框架类型是必要的,例如在这种情况下使用$arrayFromFile = [IO.File]::ReadAllLines('C:\USER\Documents\Collections\collection.txt')

System.

请注意如何从类型名称中省略[string[]]前缀。

  • 正如John的回答一样,这将返回一个"$PWD/collection.txt"数组。
  • 注意事项: 注意相对路径,因为.NET通常具有与PowerShell不同的当前目录;要解决这个问题,请始终通过绝对路径,例如:与Get-Encoding。 .NET的默认编码是UTF-8,而Windows PowerShell默认为“ANSI”编码,即系统区域设置的遗留代码页;相比之下,PowerShell Core默认为UTF-8。使用-Encoding.ReadAllLines()参数或接受编码实例的[string[]] $a = 'one', 'two'; $a[0] = 42重载来明确指定输入文件的字符编码。

[1]通常,PowerShell的隐式运行时类型转换不能提供与C#相同的类型安全性。例如,[int]不会导致错误:PowerShell只是静静地将42 qazxswpoi转换为字符串。

© www.soinside.com 2019 - 2024. All rights reserved.