通过 Powershell 抓取 txt 文件的特定部分 [英] Grabbing specific sections of a txt file via Powershell

查看:86
本文介绍了通过 Powershell 抓取 txt 文件的特定部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆