简体   繁体   English

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

[英]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或在带有(...)的更大表达式的上下文中使用管道:

  • PowerShell captures multiple output objects in an automatically created array , of type [object[]] , PowerShell自动创建的数组中捕获多个输出对象,类型为[object[]]
  • but if there's only one output object, that object is captured as-is ( without an array wrapper)如果只有一个输出对象,则该对象按原样捕获没有数组包装器)

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验证类型)。


Faster alternative: direct use of the .NET framework更快的替代方案:直接使用 .NET 框架

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.

相关问题 如何使用 Powershell 为文件中的每一行创建一个新数组? - How to do I create a new array for each line in a file with Powershell? 数组未按预期存储文本文件中的数据。 如何使用Powershell将每行的第一个单词放入数组? - Array is not storing data from text file as expected. How to get first word of each line into array using Powershell? 如何将文件的每一行保存到数组? - How do i save each line of the file to an Array? 如何将数组的内容写入文本文件,每行一个数据? - How to write content of an array to a text file, one data on each line? 如何将文本文件中的每一行分配给 PL/SQL 中的数组? - How to assign each line in a text file to an array in PL/SQL? Java:如何读取文本文件的每一行并将每一行设置为数组元素? - Java: How do you read each line of a text file and setting each line as an array element? 将文本文件的每一行转换为数组c - Turn each line of a text file into an array c 将文本文件的每一行存储到数组中 - Storing each line of a text file into an array 循环文本并将每一行放在PHP数组中 - Looping through text and putting each line in an array PHP 如何从文件循环遍历多行数组并将每一行分配给多个参数? - How to loop through multiline array from a file and assign each line to multiple arguments?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM