simple formatting a txt file for equal space

by suave9987 at 2012-09-17 08:44:03

Hello All!

I have a simple txt file that looks like this:

A00000015141433C ARASI_UICC-Interop_v1.0.1
A00000015141434C ARAM_UICC-Interop_v1.0.1
A00000015141435C ARAC_UICC-Interop_v1.0.1
A000000045463200 PaymentBridge Variable (2)
A00000000F0002FFF1F5108900000920 NSET Changer application Variable (2)

And all I want to do is simply have the same number of space between each string and have the txt formatted like so:

a user uploaded image
I had to snip a picture to show what i want because this forum will format the txt.


So basically everytime there is a space, I would like to put a specific amount of space in between all of the strings.

I thought I would do this:

Function Stripper{
$source_folder = "$getAIDFolder\Extracted AID"
$dest_folder = "$getAIDFolder\Extracted AID"
cd $source_folder
foreach ($file in (dir $source_folder |? {!($.psIsContainer)})) {
(Get-Content $file.fullname)|Foreach-Object {
$
-replace ’ ', ‘\s’
}| Set-Content "$dest_folder"
}
}
Stripper


but one, I get this error:

a user uploaded image

and I know this script I have written will not put an equal amount of space in between each string.

So please what do you all think I should do/correct with my script.

Thanks!
by juneb_msft at 2012-09-17 08:54:04
It looks like you’re accessing the directory, instead of the file.
by suave9987 at 2012-09-17 09:14:29
Well my for loop will go through and grab every file in the directory since I am wanting to format over multiple files.

I have fixed the error and changed the set-content name to $file instead of $dest_folder:

Function Stripper{
$source_folder = "$getAIDFolder\Extracted AID"
$dest_folder = "$getAIDFolder\Extracted AID"
cd $source_folder
foreach ($file in (dir $source_folder |? {!($.psIsContainer)})) {
$file.fullname
(Get-Content $file.fullname)|Foreach-Object {

$
-replace ’ ', ‘\s’
}| Set-Content "$file"
}
}
Stripper


So this works now. I just need the corect formatting sytax.

Thanks for the reply.
by poshoholic at 2012-09-17 10:30:14
For string formatting, you should look at the format operator (-f) and use it to get the width you want for the output.

For example, you can do something like this:
"{0,-20}: {1}" -f 'Label','value'
In that command, the first string (index 0) will be output into a 20-character wide buffer (that’s the number 20), left justified (the minus sign before the 20). If you want a wider label, just increase the number of 20 to something more appropriate for you. If you want the label to be right-justified, you can do that by removing the minus sign.
by suave9987 at 2012-09-17 10:46:41
Great this looks very promissing, however How would i incorporate this in my script? Would i just re write without the -replace cmdlet and then foreach-object insert something along the lines of what you have gave me? I have used this before but it was when I was outputting strings instead of manipulating.

Thanks so much!
by poshoholic at 2012-09-17 11:07:08
It seems from your file that it is space delimited, however some values may also have spaces in them which complicates things a little. I would probably read the content of the file using Get-Content, use a regular expression to separate out the values I want (i.e. something that would identify the first value as everything up to the first space, the last value as a numeric value in brackets, and anything in between as the second value), and then create the desired format either using the format command as I suggested or even easier, simply pipeline the results to Format-Table and then output that to the new text file using a wide format (see this post: http://poshoholic.com/2010/11/11/powershell-quick-tip-creating-wide-tables-with-powershell/). With that approach, you don’t even need the format operator, so the challenge becomes parsing the text you get in and converting it into an object that you can then manipulate. Here’s an untested, simple example of what that might look like:
Get-Content $file.Fullname | ForEach-Object {
$value = $_ # This should look something like this: 'A00000000F0002FFF1F5108900000920 NSET Changer applicationVariable (2)'
if ($value -match '^(\S+)\s(.+)\s((\d+))?$') {
New-Object -TypeName PSObject -Property @{
Id = $matches[1]
Value = $matches[2]
Count = $(if ($matches.Count -eq 4) {$matches[3]} else {$null})
}
}
} | Format-Table -Property Id,Value,Count
by suave9987 at 2012-09-17 11:54:16
Wow this works exceptionally well! I will tinker with it a little and make it match my specificiations. I appreciate your help.

I believe that I cannot out-file this because I receive the error of:

Set-Content : The process cannot access the file ‘C:\Users\nicalder\Desktop\Project1-Phase 2\AID\Extracted AID\AID
List - Third party .txt’ because it is being used by another process.
At line:15 char:4
+ } |set-content "$file"| Format-Table -Property Id,Value,Count
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:slight_smile: [Set-Content], IOException
+ FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.SetContentCommand

Set-Content : The process cannot access the file ‘C:\Users\nicalder\Desktop\Project1-Phase 2\AID\Extracted AID\AID
List refrence Product.txt’ because it is being used by another process.
At line:15 char:4
+ } |set-content "$file"| Format-Table -Property Id,Value,Count
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:slight_smile: [Set-Content], IOException
+ FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.SetContentCommand

Set-Content : The process cannot access the file ‘C:\Users\nicalder\Desktop\Project1-Phase 2\AID\Extracted
AID\AIDList1.txt’ because it is being used by another process.
At line:15 char:4
+ } |set-content "$file"| Format-Table -Property Id,Value,Count
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:slight_smile: [Set-Content], IOException
+ FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.SetContentCommand


I tried using out-file but this will not send any items through the out-file pipe. It actually erases all data.

Any suggestions?
by poshoholic at 2012-09-17 12:08:17
You don’t want to use Set-Content before Format-Table. The logic would be the opposite – format the table, then write it to disk. Get-Content to read the content, ForEach-Object to process it, Format-Table with -Property and -AutoSize to get a tabular output with the properties you want, Out-String to convert that to a maximum width per row, and then Out-File to write it to disk. Those last three in sequence are described in that blog post I linked to earlier.

Also, if you’re trying to replace the existing content in those files, you might want to read and store the content with Get-Content so that the file is not in use later when you write it, then process it, then write it back to disk.

You should probably also back up your files to make sure you don’t accidentally lose anything.
by suave9987 at 2012-09-17 12:17:31
Thanks a ton Kirk. I will read the article and will also try to incoropate all of your ideas here. I appreciate this.

Thanks and I will update you on my progress.