通过 Powershell 抓取 txt 文件的特定部分 [英] Grabbing specific sections of a txt file via Powershell
问题描述
我是 Powershell 脚本的新手,但我觉得我忽略了一个简单的答案,希望你们中的一些人可以提供帮助.
I am new to Powershell scripting, but I feel I am overlooking a simple answer, hopefully some of you can help.
我的公司从我们所有的计算机导出文件,其中有一个位于映射网络打印机"中间的部分.它看起来像这样:
My company exports files from all of our computers with a section around the middle of Mapped Network Printers. It looks like this:
-------------------------------------------------------------------------
Mapped Network Printers:
NetworkAddress\HP425DN [DEFAULT PRINTER]
-------------------------------------------------------------------------
Local Printers:
我被要求做的只是将映射网络打印机复制到一个新的文本文件中.
What I have been asked to do is copy just the Mapped Network Printers to a new text file.
我尝试使用带有上下文参数的 Select-String,但我无法知道有多少网络打印机,所以我无法猜测.
I tried using Select-String with a context parameter, but I have no way of knowing how many network printers there are, so I can't guess.
我也尝试使用在本网站上找到的以下代码,但它什么也没返回:
I also tried using the following code which I found on this site, but it returns nothing:
$MapPrint = gc C:\Users\User1\Documents\Config.txt
$from = ($MapPrint | Select-String -pattern "Mapped Network Printers:" |
Select-Object LineNumber).LineNumber
$to = ($MapPrint | Select-String -pattern "-------------------------------
--------------------------------------------" | Select-Object
LineNumber).LineNumber
$i = 0
$array = @()
foreach ($line in $MapPrint)
{
foreach-object { $i++ }
if (($i -gt $from) -and ($i -lt $to))
{
$array += $line
}
}
$array
我基本上想从映射网络打印机"开始搜索并在------"的下一行结束
I basically want to start the search at "Mapped Network Printers" and end it at the next row of "------"
任何帮助将不胜感激.
推荐答案
Select-String
没有基于 content<提取 范围 行的功能.
Select-String
has no feature for extracting a range of lines based on content.
最简单的方法是读取文件整体并使用-replace
操作符通过正则表达式(regex)提取范围:
The simplest approach is to read the file as a whole and use the -replace
operator to extract the range via a regular expression (regex):
$file = 'C:\Users\User1\Documents\Config.txt'
$regex = '(?sm).*^Mapped Network Printers:\r?\n(.*?)\r?\n---------------------.*'
(Get-Content -Raw $file) -replace $regex, '$1'
如果文件太大而无法放入内存,则整体读取输入文件可能会出现问题,但这可能不是您关心的问题.
从好的方面来说,这种方法比处理循环中的行要快得多.
Reading an input file as a whole can be problematic with files too large to fit into memory, but that's probably not a concern for you.
On the plus side, this approach is much faster than processing the lines in a loop.
Get-Content -Raw
(PSv3+) 读取输入文件整体.
Get-Content -Raw
(PSv3+) reads the input file as a whole.
内联正则表达式选项 (?sm)
打开 m 多行和 s 单行选项:
Inline regex options (?sm)
turn on both the multi-line and the single-line option:
m
表示^
和$
匹配每一行的开头和结尾而不是输入字符串作为一个整体.s
表示元字符.
也匹配\n
个字符,所以像.*
这样的表达式可用于跨行匹配.
m
means that^
and$
match the start and end of each line rather than the input string as a whole.s
means that metacharacter.
matches\n
characters too, so that an expression such as.*
can be used to match across lines.
\r?\n
匹配单个换行符,包括 CRLF 和 LF 变体.
\r?\n
matches a single line break, both the CRLF and the LF variety.
(.*?)
是捕获组(非贪婪地)捕获边界线之间的所有内容.
(.*?)
is the capture group that (non-greedily) captures everything between the bounding lines.
请注意,正则表达式匹配整个输入字符串,然后只用感兴趣的子字符串(范围)替换它,在第一个(也是唯一一个)捕获组中捕获($1
).
Note that the regex matches the entire input string, and then replaces it with just the substring (range) of interest, captured in the 1st (and only) capture group ($1
).
假设 $file
包含:
-------------------------------------------------------------------------
Mapped Network Printers:
NetworkAddress\HP425DN [DEFAULT PRINTER]
NetworkAddress\HP426DN
-------------------------------------------------------------------------
Local Printers:
以上产生:
NetworkAddress\HP425DN [DEFAULT PRINTER]
NetworkAddress\HP426DN
这篇关于通过 Powershell 抓取 txt 文件的特定部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!