通过正则表达式从行中提取特定的多个字符串

时间:2019-02-28 08:29:17

标签: powershell

我一直在尝试使用PowerShell从.txt文件中的多行提取某些值。我有一个巨大的文件,其中包含所有备份,并尝试提取所有这些行。

TXT文件:

Api.fetchAll({columns: ['username','password']})
.then(function(employee)
{
	return employee.toJSON();
})
.then(function(employee){
	app.use(basicAuth({
			users: {employee}
		}));
});

到目前为止,我已经有代码:

Backup-ID:           hostname01
Policy:              VM_weekly
Primary Copy:        23
Expires:             1/5/2024 3:19:13 AM
Type:                4


Copy Number:        2
Fragment Size (KB): 6188832
Expires:            1/5/2024 3:19:13 AM
MediaID:            XXX122
TestID:             1222
Block:              33


Copy Number:        3
Fragment Size (KB): 6188832
Expires:            1/5/2024 3:19:13 AM
MediaID:            XXX134
TestID:             223
Block:              22
Duplicate:          N



Backup-ID:           hostname02
Policy:              VM_weekly2
Primary Copy:        24
Expires:             1/5/2024 3:19:13 AM
Type:                2


Copy Number:        2
Fragment Size (KB): 6188832
Expires:            1/5/2024 3:19:13 AM
MediaID:            XXX244
Comp:               BBB
Block:              45
Duplicate:          N


Copy Number:        3
Fragment Size (KB): 6188832
Expires:            1/5/2024 3:19:13 AM
MediaID:            XXX199
Comp:               AA
Block:              334

Copy Number:        4
Fragment Size (KB): 6188832
Expires:            1/5/2024 3:19:13 AM
MediaID:            XXX177

这就是我想要的:

Get-Content C:\test.txt | Select-String -Pattern 'Backup-ID: ' ,'Policy: ' ,'Primary Copy: ' ,'Expires:  ' ,'Copy Number: ' , 'Fragment Size ' ,'Expires: ' , 'MediaID:'

3 个答案:

答案 0 :(得分:2)

这是我的老派做法:

#include "pch.h"
#include <iostream>
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdlib.h>
#pragma comment(lib, "IPHLPAPI.lib")
#include <Windows.h>


int main()
{
    IP_ADAPTER_INFO  *pAdapterInfo;
    ULONG            ulOutBufLen;
    DWORD            dwRetVal;

    pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
    ulOutBufLen = sizeof(IP_ADAPTER_INFO);


    if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) != ERROR_SUCCESS) {
        free(pAdapterInfo);
        pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);
    }

    if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) != ERROR_SUCCESS) {
        printf("GetAdaptersInfo call failed with %d\n", dwRetVal);
    }

    PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
    while (pAdapter) {
        if (pAdapter->Type == MIB_IF_TYPE_ETHERNET)
        {
            if (pAdapter->DhcpEnabled) {
                printf("\tDHCP Enabled: Yes\n");
                printf("\t\tDHCP Server: \t%s\n", pAdapter->DhcpServer.IpAddress.String);
            }
            else
                printf("\tDHCP Enabled: No\n");

            printf("\t***\n");

            printf("Adapter Name: %s\n", pAdapter->AdapterName);
            printf("Adapter Desc: %s\n", pAdapter->Description);
            printf("\tAdapter Addr: \t");
            for (UINT i = 0; i < pAdapter->AddressLength; i++) {
                if (i == (pAdapter->AddressLength - 1))
                    printf("%.2X\n", (int)pAdapter->Address[i]);
                else
                    printf("%.2X-", (int)pAdapter->Address[i]);
            }
            printf("IP Address: %s\n", pAdapter->IpAddressList.IpAddress.String);
            printf("IP Mask: %s\n", pAdapter->IpAddressList.IpMask.String);
            printf("\tGateway: \t%s\n", pAdapter->GatewayList.IpAddress.String);


            if (pAdapter->Type == MIB_IF_TYPE_ETHERNET)
                printf("\tIt's an Ethernet NIC\n");
            else if (pAdapter->Type == IF_TYPE_IEEE80211)
                printf("\tIt's an Wifi NIC\n");
        }
        pAdapter = pAdapter->Next;

    }
    getchar();
}

输出

$line = ''
Get-Content C:\test.txt | 
    Select-String -Pattern 'Backup-ID: ' ,'Policy: ' ,'Primary Copy: ' ,'Expires:  ' ,'Copy Number: ' , 'Fragment Size ' ,'Expires: ' , 'MediaID:' |
        ForEach-Object {
            $aux = $_  -split ':',2            # only 2 substrings
            if ($aux[0] -eq 'Backup-ID') {
                if ( $line -ne '' ) { $line }  # Write-Output (current line)
                $line = $aux[1].Trim()
            } else {
                $line += ',' + $aux[1].Trim()
            }
        }
        $line                                   # Write-Output (last line)
D:\PShell\SO\54921319.ps1

编辑: ...我需要导出CSV文件...

hostname01,VM_weekly,23,1/5/2024 3:19:13 AM,2,6188832,1/5/2024 3:19:13 AM,XXX122,3,6188832,1/5/2024 3:19:13 AM,XXX134
hostname02,VM_weekly2,24,1/5/2024 3:19:13 AM,2,6188832,1/5/2024 3:19:13 AM,XXX244,3,6188832,1/5/2024 3:19:13 AM,XXX199,4,6188832,1/5/2024 3:19:13 AM,XXX177

当然,您可以计算

  • $xArr = D:\PShell\SO\54921319.ps1 $xCsv = $xArr | ConvertFrom-Csv -Header $(1..30|%{"a$_"}) $xcsv | Export-Csv -NoTypeInformation -Path c:\temp\result.csv 的实际上限,而不是估计的 -Header $(1..30|%{"a$_"}),例如为30
  • 甚至计算一些可读的标头(请记住给定($xArr | % {$_.Split(',').Count}|Measure-Object -Maximum).Maximum内每个Copy Number的某些属性的重复名称)

答案 1 :(得分:2)

使用更好的模式

 $Pattern = '^Backup-ID|^Policy|^Primary Copy|^Expires|^Copy Number|^Fragment Size|^Expires|^MediaID'

和RegEx将输出拆分到Backup-ID

(Get-Content .\test.txt|Select-String -Pattern $Pattern|Out-String) -split "(?=Backup-ID)"|ForEach-Object {
    (($_ -split "`r?`n" | %{($_ -split ":\s+",2)[1]}) -join ',').Trim(',')
}

hostname01,VM_weekly,23,1/5/2024 3:19:13 AM,2,6188832,1/5/2024 3:19:13 AM,XXX122,3,6188832,1/5/2024 3:19:13 AM,XXX134
hostname02,VM_weekly2,24,1/5/2024 3:19:13 AM,2,6188832,1/5/2024 3:19:13 AM,XXX244,3,6188832,1/5/2024 3:19:13 AM,XXX199,4,6188832,1/5/2024 3:19:13 AM,XXX177

答案 2 :(得分:1)

这也许吗?

& {
    $current = $null
    switch -regex -file 'C:\text.txt' {
        '^(Backup-ID|Policy|Primary Copy|Expires|Copy Number|Fragment Size \(KB\)|Expires|MediaID):\s+(.*)' {
            if ($matches[1] -eq "Backup-ID") {
                if ($current) { $current.ToString() }
                $current = [Text.StringBuilder]::new()
                [void]$current.Append($matches[2])
            }
            else {
                [void]$current.Append(",").Append($matches[2])
            }
        }
    }
    $current.ToString()
}