0

I have a little situation here which might very simple for you. Context:
I have 3 files : mobile.txt, contract.txt and name.txt All files are formatted like each line should refer to the same line on the other files...

Exemple :

  • mobile.txt
0606060606
0607070707
0608080808
  • contract.txt
123654
456985
152364
  • name.txt
John Doe
Miss 1
Mister 2

I would like a foreach like loop to extract line by line in a variable and create table as :

0606060606;123654;John Doe
0607070707;456985;Miss 1
0608080808;152364;Mister 2

Sure it's really simple for you. I only manage to store the entire file to a variable and it's not creating a table.

Cheers all.

Question #2 (updated after answering question #1) :

Hello this is working fine with this method Thank you guys.

I now have a file containing 115 lines like this thanks to you :

0606060606;123654;John Doe
0607070707;456985;Miss 1
0608080808;152364;Mister 2

I have another file containing this type of content :

Smart Pro 5h 3Go ;44,00
OCC-Remise sur Smart Pro 5h 3Go ;-17,60
Abonnement Options-accès international;00,00
Abonnement Options-Option Voyage;00,00
Abonnement Options-ILLIMITE INTRA CPTE;3,00
OCC-option illimité intra-compte offerte;-3,00
----------------------- Page 30----------------------
Smart Pro 5h 3Go ;44,00
OCC-Remise sur Smart Pro 5h 3Go ;-17,60
Abonnement Options-accès international;00,00
Abonnement Options-Option Voyage;00,00
Abonnement Options-ILLIMITE INTRA CPTE;3,00
OCC-option illimité intra-compte offerte;-3,00
----------------------- Page 31----------------------
Smart Pro 5h 3Go;44,00
OCC-Remise sur Smart Pro 5h 3Go ;-17,60
Abonnement Options-ILLIMITE INTRA CPTE;3,00
OCC-option illimité intra-compte offerte ;-3,00
----------------------- Page 32----------------------

Now i have to match them like :
Line 1 of file 1 is copied to the first content between the delimiters
Line 2 of file 1 is copied to the second content between the delimiters Line 3 of file 1 is copied to the third content between the delimiters
The delimiter can be another string than the one presented with Page numbers.

I want this type of output in the final file :

0606060606;123654;John Doe;Smart Pro 5h 3Go ;44,00
0606060606;123654;John Doe;OCC-Remise sur Smart Pro 5h 3Go ;-17,60
0606060606;123654;John Doe;Abonnement Options-accès international;00,00
0606060606;123654;John Doe;Abonnement Options-Option Voyage;00,00
0606060606;123654;John Doe;Abonnement Options-ILLIMITE INTRA CPTE;3,00
0606060606;123654;John Doe;OCC-option illimité intra-compte offerte;-3,00
0607070707;456985;Miss 1;Smart Pro 5h 3Go ;44,00
0607070707;456985;Miss 1;OCC-Remise sur Smart Pro 5h 3Go ;-17,60
0607070707;456985;Miss 1;Abonnement Options-accès international;00,00
0607070707;456985;Miss 1;Abonnement Options-Option Voyage;00,00
0607070707;456985;Miss 1;Abonnement Options-ILLIMITE INTRA CPTE;3,00
0607070707;456985;Miss 1;OCC-option illimité intra-compte offerte;-3,00
0608080808;152364;Mister 2;Smart Pro 5h 3Go;44,00
0608080808;152364;Mister 2;OCC-Remise sur Smart Pro 5h 3Go ;-17,60
0608080808;152364;Mister 2;Abonnement Options-ILLIMITE INTRA CPTE;3,00
0608080808;152364;Mister 2;OCC-option illimité intra-compte offerte ;-3,00

I am stuck in a neverending loop...

1
  • 6
    Could you share with us your attempt at solving this problem? Commented Dec 3, 2021 at 14:30

2 Answers 2

1

You use

$mobile_txt   = @( Get-Content mobile.txt )
$contract_txt = @( Get-Content contract.txt )
$name_txt     = @( Get-Content name.txt )

instead of hard-coded files:

$mobile_txt = @'
0606060606
0607070707
0608080808
'@ -split [System.Environment]::NewLine
$contract_txt = @'
123654
456985
152364
'@ -split [System.Environment]::NewLine
$name_txt = @'
John Doe
Miss 1
Mister 2
'@ -split [System.Environment]::NewLine

for ( $ii = 0;
      $ii -lt ( ( $mobile_txt.Count,
                $contract_txt.Count,
                $name_txt.Count | Measure-Object -Minimum).Minimum);
      $ii++ )
{
    [PSCustomObject] @{
        mobile   = $mobile_txt[$ii];
        contract = $contract_txt[$ii];
        name     = $name_txt[$ii]
    };
}

Result: .\SO\70215879.ps1

mobile     contract name    
------     -------- ----    
0606060606 123654   John Doe
0607070707 456985   Miss 1  
0608080808 152364   Mister 2
Sign up to request clarification or add additional context in comments.

6 Comments

I think it should be -Maximum).Maximum instead of -Minimum).Minimum, right?
@SantiagoSquarzon No. If counts are (respectively) 3, 3, 2 then Maximum is 3 and $name_txt[2] leads to error Index was outside the bounds of the array.
Not sure what you mean, (1,2,3)[3] will just return null not an exception. Besides, if one of the arrays has 20 more elements than the others, would you just truncate it?
I use Set-StrictMode -Version latest setting and (1,2,3)[3] leads to Index was outside the bounds of the array. And yes, truncating is a consequence of badly structured task…
@SantiagoSquarzon I know that Set-StrictMode is turned off by default. However, I'd consider it's a poor practice, see e.g. powershell-guru - although it's merely an opinion: the PowerShell default can be both a blessing and a curse
|
0

The files may not all have the same number of lines and in that case it is easy to lose information.
To allow for that, and create output for all lines, but with possible empty fieds, you could read the files in and create Hashtables from the lines.

$i = 0
$mobile = @{}
Get-Content -Path 'X:\mobile.txt' | ForEach-Object { $mobile[$i++] = $_ }

$i = 0
$contract = @{}
Get-Content -Path 'X:\contract.txt' | ForEach-Object { $contract[$i++] = $_ }

$i = 0
$name = @{}
Get-Content -Path 'X:\name.txt' | ForEach-Object { $name[$i++] = $_ }

# determine the maximum number of lines found in tthe input files
$maxItems = ($mobile.Count, $name.Count, $contract.Count | Measure-Object -Maximum).Maximum

# next, combine and output.
# this won't throw an exception if an item is not present 
# in any of the files, but insert an empty field instead.
for ($i = 0; $i -lt $maxItems; $i++) {
    output a line as shown in your question
    '{0};{1};{2}' -f $mobile[$i], $contract[$i], $name[$i]
}

Or if I may suggest, combine as object, to later save as CSV file

$result = for ($i = 0; $i -lt $maxItems; $i++) {
    # output an object that gets collected in variable $result
    [PsCustomObject]@{
        Mobile   = $mobile[$i]
        Contract = $contract[$i]
        Name     = $name[$i]
    }
}
# view on console
$result

# write to CSV file
$result | Export-Csv -Path 'X:\MobileCombined.csv' -Delimiter ';' -NoTypeInformation

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.