如何通过powershell将文本文件的每一行保存为数组
How to save each line of text file as array through powershell
如果我有一个文本文件,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。
Get-Content
命令returns文本文件中的每一行作为一个单独的字符串,所以会给你一个数组(只要你不使用-Raw
参数; 这会导致所有行合并为一个字符串)。
[string[]]$arrayFromFile = Get-Content -Path 'C:\USER\Documents\Collections\collection.txt'
在 中,mklement0 提供了更多关于调用此命令时实际发生的事情的详细信息,以及如果您关心性能而不是便利性的替代方法。如果您有兴趣了解更多关于该语言的知识,而不是仅仅解决这个一次性要求,那么绝对值得一读。
补充:
Get-Content
, as a cmdlet, outputs objects one by one to the pipeline、可用时.(请注意,即使在没有管道符号的情况下调用 cmdlet 也会涉及管道, |
, 用于链接 多个 命令)。
在这种情况下,输出对象是输入文本文件的各个 行 。
如果您收集管道的输出对象,例如通过将其分配给变量 例如 $arrayFromFile
或在具有 (...)
:
的较大表达式的上下文中使用管道
- PowerShell 在自动创建的数组中捕获多个输出对象,类型为
[object[]]
,
- 但是如果只有一个输出对象,该对象被捕获原样 (没有 数组包装器)
但是,通常没有必要确保您总是收到数组,因为 PowerShell 在许多上下文中将 scalars(非集合的单个值)与 arrays(集合)相同,例如 foreach
statements or when outputting a value to be enumerated to the pipeline, to be processed via the ForEach-Object
cmdlet,例如;因此,无论输入文件包含多少行,以下命令都可以正常工作:
# OK - read all lines, then process them one by one in the loop.
# (No strict need to collect the Get-Content output in a variable first.)
foreach ($line in Get-Content C:\USER\Documents\Collections\collection.txt) {
newman run $line
}
# Alternative, using the pipeline:
# Read line by line, and pass each through the pipeline, as it is being
# read, to the ForEach-Object cmdlet.
# Note the use of automatic variable $_ to refer to the line at hand.
Get-Content C:\USER\Documents\Collections\collection.txt |
ForEach-Object { newman run $_ }
为了确保命令的输出总是一个数组,PowerShell 提供了@(...)
, the array-subexpression operator,它甚至可以包装单个-数组中的对象输出。
因此,PowerShell 惯用的解决方案 是:
$arrayFromFile = @(Get-Content C:\USER\Documents\Collections\collection.txt)
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
变为 type-constrained,这意味着它的数据类型被锁定在(而默认情况下,PowerShell 允许您随时更改变量的类型)。
[array]
是 John 的回答 [string[]]
中使用的 type-specific cast 的独立于命令的替代方法;您可以使用后者来强制跨数组元素使用统一类型,但这在 PowerShell[1] 中通常不是必需的
.
常规 PowerShell 数组的类型为 [object[]]
,它允许混合不同类型的元素,但任何给定元素仍然具有特定类型;例如,即使上面命令后 $arrayFromFile
的类型是 [object[]]
,$arrayFromFile[0]
的类型,即第一个元素,例如,是 [string]
(假设文件至少包含 1 行;使用 $arrayFromFile[0].GetType().Name
).
验证类型
更快的选择:直接使用 .NET 框架
Cmdlet 和管道提供了高级的、潜在的内存限制功能,这些功能具有表现力和方便性,但它们可能 慢。
当性能很重要时,直接使用 .NET 框架类型是必要的,例如本例中的 [System.IO.File]
。
$arrayFromFile = [IO.File]::ReadAllLines('C:\USER\Documents\Collections\collection.txt')
请注意如何从类型名称中省略 System.
前缀。
正如约翰的回答,这将 return 一个 [string[]]
数组。
注意事项:
注意 相对 路径,因为 .NET 通常与 PowerShell 有一个 不同 当前目录;要解决这个问题,总是传递绝对路径,在最简单的情况下,例如,"$PWD/collection.txt"
,最稳健的是[=126] =]
"$((Get-Location -PSProvider FileSystem).ProviderPath)/collection.txt"
.NET 的默认编码为 UTF-8,而 Windows PowerShell 默认为“ANSI”编码, i.e.the 系统语言环境的遗留代码页; PowerShell Core (v6+),相比之下,也默认为 UTF-8。使用 Get-Encoding
的 -Encoding
参数或接受编码实例的 .ReadAllLines()
重载来明确指定输入文件的字符编码。
[1] 通常,PowerShell 的隐式运行时类型转换无法提供与 C# 中相同的类型安全性。例如,[string[]] $a = 'one', 'two'; $a[0] = 42
不会 导致错误:PowerShell 只是悄悄地将 [int]
42
转换为字符串。
$array = Get-Content -Path @("C:\tmp\sample.txt")
foreach($item in $array)
{
write-host $item
}
如果我有一个文本文件,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。
Get-Content
命令returns文本文件中的每一行作为一个单独的字符串,所以会给你一个数组(只要你不使用-Raw
参数; 这会导致所有行合并为一个字符串)。
[string[]]$arrayFromFile = Get-Content -Path 'C:\USER\Documents\Collections\collection.txt'
在
补充
Get-Content
, as a cmdlet, outputs objects one by one to the pipeline、可用时.(请注意,即使在没有管道符号的情况下调用 cmdlet 也会涉及管道, |
, 用于链接 多个 命令)。
在这种情况下,输出对象是输入文本文件的各个 行 。
如果您收集管道的输出对象,例如通过将其分配给变量 例如 $arrayFromFile
或在具有 (...)
:
- PowerShell 在自动创建的数组中捕获多个输出对象,类型为
[object[]]
, - 但是如果只有一个输出对象,该对象被捕获原样 (没有 数组包装器)
但是,通常没有必要确保您总是收到数组,因为 PowerShell 在许多上下文中将 scalars(非集合的单个值)与 arrays(集合)相同,例如 foreach
statements or when outputting a value to be enumerated to the pipeline, to be processed via the ForEach-Object
cmdlet,例如;因此,无论输入文件包含多少行,以下命令都可以正常工作:
# OK - read all lines, then process them one by one in the loop.
# (No strict need to collect the Get-Content output in a variable first.)
foreach ($line in Get-Content C:\USER\Documents\Collections\collection.txt) {
newman run $line
}
# Alternative, using the pipeline:
# Read line by line, and pass each through the pipeline, as it is being
# read, to the ForEach-Object cmdlet.
# Note the use of automatic variable $_ to refer to the line at hand.
Get-Content C:\USER\Documents\Collections\collection.txt |
ForEach-Object { newman run $_ }
为了确保命令的输出总是一个数组,PowerShell 提供了@(...)
, the array-subexpression operator,它甚至可以包装单个-数组中的对象输出。
因此,PowerShell 惯用的解决方案 是:
$arrayFromFile = @(Get-Content C:\USER\Documents\Collections\collection.txt)
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
变为 type-constrained,这意味着它的数据类型被锁定在(而默认情况下,PowerShell 允许您随时更改变量的类型)。
[array]
是 John 的回答 [string[]]
中使用的 type-specific cast 的独立于命令的替代方法;您可以使用后者来强制跨数组元素使用统一类型,但这在 PowerShell[1] 中通常不是必需的
.
常规 PowerShell 数组的类型为 [object[]]
,它允许混合不同类型的元素,但任何给定元素仍然具有特定类型;例如,即使上面命令后 $arrayFromFile
的类型是 [object[]]
,$arrayFromFile[0]
的类型,即第一个元素,例如,是 [string]
(假设文件至少包含 1 行;使用 $arrayFromFile[0].GetType().Name
).
更快的选择:直接使用 .NET 框架
Cmdlet 和管道提供了高级的、潜在的内存限制功能,这些功能具有表现力和方便性,但它们可能 慢。
当性能很重要时,直接使用 .NET 框架类型是必要的,例如本例中的 [System.IO.File]
。
$arrayFromFile = [IO.File]::ReadAllLines('C:\USER\Documents\Collections\collection.txt')
请注意如何从类型名称中省略 System.
前缀。
正如约翰的回答,这将 return 一个
[string[]]
数组。注意事项:
注意 相对 路径,因为 .NET 通常与 PowerShell 有一个 不同 当前目录;要解决这个问题,总是传递绝对路径,在最简单的情况下,例如,
"$PWD/collection.txt"
,最稳健的是[=126] =]"$((Get-Location -PSProvider FileSystem).ProviderPath)/collection.txt"
.NET 的默认编码为 UTF-8,而 Windows PowerShell 默认为“ANSI”编码, i.e.the 系统语言环境的遗留代码页; PowerShell Core (v6+),相比之下,也默认为 UTF-8。使用
Get-Encoding
的-Encoding
参数或接受编码实例的.ReadAllLines()
重载来明确指定输入文件的字符编码。
[1] 通常,PowerShell 的隐式运行时类型转换无法提供与 C# 中相同的类型安全性。例如,[string[]] $a = 'one', 'two'; $a[0] = 42
不会 导致错误:PowerShell 只是悄悄地将 [int]
42
转换为字符串。
$array = Get-Content -Path @("C:\tmp\sample.txt")
foreach($item in $array)
{
write-host $item
}