[英]How to save each line of text file as array through powershell
If I have a text file, C:\USER\Documents\Collections\collection.txt that has the following information:如果我有一个文本文件,C:\USER\Documents\Collections\collection.txt 包含以下信息:
collectionA.json
collectionB.json
collectionC.json
collectionD.json
I am wondering how, through Powershell, I am able to store each line in the text file as elements of an array such as..我想知道如何通过 Powershell 将文本文件中的每一行存储为数组的元素,例如..
array arrayFromFile = new Array;
foreach(line x in collection.txt)
{
arrayFromFile.Add(x);
}
..with the end goal of doing the following: ..最终目标是执行以下操作:
foreach(string x in arrayFromFile)
{
newman run x;
}
My apologies for the seemingly easy question - I have never dealt with Powershell before.对于这个看似简单的问题,我深表歉意——我以前从未处理过 Powershell。
The Get-Content
command returns each line from a text file as a separate string, so will give you an array (so long as you don't use the -Raw
parameter; which causes all lines to be combined to a single string). Get-Content
命令将文本文件中的每一行作为单独的字符串返回,因此会给您一个数组(只要您不使用-Raw
参数;这会导致所有行合并为一个字符串)。
[string[]]$arrayFromFile = Get-Content -Path 'C:\USER\Documents\Collections\collection.txt'
In his excellent answer , mklement0 gives a lot more detail on what's really going on when you call this command, as well as alternate approaches if you're concerned about performance over convenience.在他出色的回答中,mklement0 提供了更多关于调用此命令时实际发生的情况的详细信息,以及如果您担心性能而不是便利性的替代方法。 Definitely worth a read if you're interested in learning more about the language rather than just solving this one off requirement.
如果您有兴趣了解更多有关该语言的知识,而不仅仅是解决这一一次性要求,那么绝对值得一读。
To complement JohnLBevan's helpful answer :为了补充JohnLBevan 的有用答案:
Get-Content
, as a cmdlet , outputs objects one by one to the pipeline , as they become available . Get-Content
作为一个cmdlet ,在对象可用时将它们一一输出到管道。 (Note that a pipeline is involved even when invoking a cmdlet in the absence of the pipe symbol, |
, the latter being required for chaining multiple commands). (请注意,即使在没有管道符号
|
的情况下调用 cmdlet 也会涉及管道,后者是链接多个命令所必需的)。
In this case, the output objects are the individual lines of the input text file.在这种情况下,输出对象是输入文本文件的各个行。
If you collect a pipeline's output objects , such as by assigning it to a variable such as $arrayFromFile
or by using the pipeline in the context of a larger expression with (...)
:如果您收集管道的输出对象,例如通过将其分配给变量(如
$arrayFromFile
或在带有(...)
的更大表达式的上下文中使用管道:
[object[]]
, [object[]]
, However, it often isn't necessary to ensure that you always receive an array , because PowerShell treats scalars (single values that aren't collections) the same as arrays (collections) in many contexts, such as in foreach
statements or when outputting a value to be enumerated to the pipeline, to be processed via the ForEach-Object
cmdlet, for instance;但是,通常没有必要确保您始终收到一个数组,因为 PowerShell 在许多上下文中将标量(不是集合的单个值)与数组(集合)相同,例如在
foreach
语句中或输出时枚举到管道的值,例如通过ForEach-Object
cmdlet 进行处理; therefore, the following commands work just fine, irrespective of how many lines the input file contains:因此,无论输入文件包含多少行,以下命令都可以正常工作:
# 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 $_ }
In order to ensure that a command's output is always an array, PowerShell offers @(...)
, the array-subexpression operator , which wraps even single-object output in an array.为了确保命令的输出始终是一个数组,PowerShell 提供了
@(...)
数组子表达式运算符,它甚至将单个对象的输出包装在一个数组中。
Therefore, the PowerShell-idiomatic solution is:因此, PowerShell 惯用的解决方案是:
$arrayFromFile = @(Get-Content C:\USER\Documents\Collections\collection.txt)
TheMadTechnician points out that you can also use [array]
to cast / type-constrain pipeline output as an alternative to @(...)
, which also creates [object[]]
arrays : 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
By using [array] $arrayFromFile = ...
rather than $arrayFromFile = [array] (...)
, variable $arrayFromFile
becomes type-constrained , which means that its data type is locked in (whereas by default PowerShell allows you to change the type of a variable anytime).通过使用
[array] $arrayFromFile = ...
而不是$arrayFromFile = [array] (...)
,变量$arrayFromFile
变为type-constrained ,这意味着它的数据类型被锁定(而默认情况下 PowerShell 允许您随时更改变量的类型)。
[array]
is a command-independent alternative to the type-specific cast used in John's answer, [string[]]
; [array]
是 John 的答案[string[]]
中使用的特定类型强制转换的与命令无关的替代方案; you may use the latter for enforcing use of a uniform type across the array's elements, but that is often not necessary in PowerShell [1] .您可以使用后者来强制在数组元素中使用统一类型,但这在 PowerShell [1]中通常不是必需的。
Regular PowerShell arrays are of type [object[]]
, which allows mixing elements of different types, but any given element still has a specific type;常规 PowerShell 数组的类型为
[object[]]
,它允许混合不同类型的元素,但任何给定元素仍然具有特定类型; eg, even though the type of $arrayFromFile
after the command above is [object[]]
, the type of $arrayFromFile[0]
, ie the 1st element, for instance, is [string]
(assuming that the file contained at least 1 line; verify the type with $arrayFromFile[0].GetType().Name
).例如,即使上面命令之后的
$arrayFromFile
的类型是[object[]]
, $arrayFromFile[0]
的类型,即第一个元素,例如,是[string]
(假设文件包含至少 1行;使用$arrayFromFile[0].GetType().Name
验证类型)。
Cmdlets and the pipeline offer high-level, potentially memory-throttling features that are expressive and convenient, but they can be slow . Cmdlet 和管道提供了高级的、潜在的内存限制功能,这些功能具有表现力和便利性,但它们可能很慢。
When performance matters, direct use of .NET framework types is necessary, such as [System.IO.File]
in this case.当性能很重要时,需要直接使用 .NET 框架类型,例如本例中的
[System.IO.File]
。
$arrayFromFile = [IO.File]::ReadAllLines('C:\USER\Documents\Collections\collection.txt')
Note how the System.
注意
System.
prefix can be omitted from the type name.前缀可以从类型名称中省略。
As in John's answer, this will return a [string[]]
array.正如约翰的回答,这将返回一个
[string[]]
数组。
Caveats :注意事项:
Be careful with relative paths, as .NET typically has a different current directory than PowerShell;请注意相对路径,因为 .NET 通常具有与 PowerShell不同的当前目录; to work around this, always pass absolute paths , in the simplest case with, eg,
"$PWD/collection.txt"
and most robustly with要解决此问题,请始终传递绝对路径,在最简单的情况下使用
"$PWD/collection.txt"
,最稳健的是使用"$((Get-Location -PSProvider FileSystem).ProviderPath)/collection.txt"
.NET's default encoding is UTF-8, whereas Windows PowerShell defaults to "ANSI" encoding , iethe system locale's legacy code page; .NET 的默认编码为 UTF-8,而Windows PowerShell默认为“ANSI”编码,即系统区域设置的旧代码页; PowerShell Core (v6+), by contrast, also defaults to UTF-8 .
相比之下,PowerShell Core (v6+) 也默认为 UTF-8 。 Use
Get-Encoding
's -Encoding
parameter or the .ReadAllLines()
overload that accepts an encoding instance to specify the input file's character encoding explicitly.使用
Get-Encoding
的-Encoding
参数或接受编码实例的.ReadAllLines()
重载来明确指定输入文件的字符编码。
[1] Generally, PowerShell's implicit, runtime type conversions cannot provide the same type safety you'd get in C#, for instance. [1] 通常,例如,PowerShell 的隐式运行时类型转换无法提供与 C# 相同的类型安全性。 Eg,
[string[]] $a = 'one', 'two'; $a[0] = 42
例如,
[string[]] $a = 'one', 'two'; $a[0] = 42
[string[]] $a = 'one', 'two'; $a[0] = 42
does not cause an error: PowerShell simply quietly converts [int]
42
to a string. [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
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.