How can I save lines with spaces between characters in the right way (Array)?

自古美人都是妖i 提交于 2020-01-16 18:22:12

问题


Two examples of Lines:

Bob                     02 02 10 80   Enquiries            
Martin      Corp        02 02 10 80   Langar               

Note, that the first line doesn't have an information after "Bob", so just spaces.

So my code would be:

$account_name = $inputFileContent[$i].Split(" ",[System.StringSplitOptions]::RemoveEmptyEntries)

Edit: My output-array should be like:

$account_name =
Bob
(Empty Line)
02
02
10
80
Enquiries

Is there a way to change the code, so I have it saved in a array in that format?


回答1:


One possibility is to use regular expressions:

Get-Content "data.txt" | ForEach-Object {
    $_ -match "^([a-z]+) +(\w*) +((?:\d{2} ){3}\d{2}) +(\w+)$" | Out-Null

    $account_name = 1..4 | ForEach-Object {$matches[$_]}
}

This will set $account_name to:

Bob

02 02 10 80
Enquiries

or:

Martin
Corp
02 02 10 80
Langar

Of course, $account_name is over-written each time, so either use it before looping around to the next line, or add each set of items to an array.

Note: I assumed you actually wanted the 'code' as a single item (e.g. '02 02 10 80'), but if not, the pattern can be adjusted to pull out the individual items.




回答2:


Your input lines contain fixed width as opposite to comma separate values, so you can't use a delimiter (space) to parse the data which may contain empty values. Instead you have to use the position of the values in the string.

Here is an example line, which I have added index numbering above:

 012345678901234567890123456789012345678901234567890
  Martin      Corp        02 02 10 80   Langar

You can notice the first value Martin starts from the second character, index number 1 and is at most 12 characters long. Second value Corp starts from index 13 and is at most 11 characters long, after which first value 02 starts and so on.

We use substring(1,12) to get a 12 characters long slice from the line starting from index 1. To remove (trailing) empty spaces from the string, we call Trim() method.

To create a new object containing data of each line, we use [PSCustomObject] and give names to object properties, or headers if you wish. += operator adds that object to the array.

test.txt

 Bob                     02 02 10 80   Enquiries            
 Martin      Corp        02 02 10 80   Langar

Script:

$array = @() # Create an empty array

Get-Content .\test.txt | foreach{ # Read test.txt file and handle each line with foreach
    $array += [PSCustomObject]@{
        Field1 = $_.substring(1,12).Trim();
        Field2 = $_.substring(13,11).Trim();
        Field3 = $_.substring(25,2).Trim();
        Field4 = $_.substring(28,2).Trim();
        Field5 = $_.substring(31,2).Trim();
        Field6 = $_.substring(34,2).Trim();
        Field7 = $_.substring(39); # Substring from index 39 to the end of line
    }
}

$array

To output the values each on its own line, you could do it for example by this:

$array | foreach{
    $_.Field1
    $_.Field2
    $_.Field3
    $_.Field4
    $_.Field5
    $_.Field6
    $_.Field7
}



回答3:


ConvertFrom-SourceTable

A while ago, I have created a ConvertFrom-SourceTable cmdlet for reading fixed tables like yours:

$Text = '
 Bob                     02 02 10 80   Enquiries
 Martin      Corp        02 02 10 80   Langar'

-Header

As your $Text example has no header you just need to provide it for each column, e.g.:

ConvertFrom-SourceTable -Header Name,Company,A,B,C,D,Comment $Text | Format-Table

Name   Company A  B  C  D  Comment
----   ------- -  -  -  -  -------
Bob            02 02 10 80 Enquiries
Martin Corp    02 02 10 80 Langar

02 02 10 80

You might also define the -Header nas a single string which is than used to not just the column names but also the alignment of the columns. In your example, if 02 02 10 80 is actually a single column, you can just add a single column header for this column:

ConvertFrom-SourceTable $Text -Header ' Name        Company     Code          Comment' | Format-Table

Name   Company Code        Comment
----   ------- ----        -------
Bob            02 02 10 80 Enquiries
Martin Corp    02 02 10 80 Langar

As long as you keep the surrounding columns Company and Comment (including the header) also left aligned. If that is not the case (and in some seldom other situations), you might also add a -Ruler parameter (see Help ConvertFrom-SourceTable -Full) to further define the alignment of your table.

Specific to your answer:

As you can see from the example, the ConvertFrom-SourceTable cmdlet returns a list of objects (common to most other cmdlets) which you can easialy pipe to native cmdlets like Where-Object and ForEach-Object. In you specific case you might do something like this:

$Accounts = ConvertFrom-SourceTable $Text -Header `
' Name        Company     Code          Comment'

(($Accounts | Where-Object Name -eq 'Bob').PSObject.Properties).Value

Resulting in:

Bob

02 02 10 80
Enquiries


来源:https://stackoverflow.com/questions/54125650/how-can-i-save-lines-with-spaces-between-characters-in-the-right-way-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!