From time to time i get a request from a dept head to do a query in a DB and dump the results then alter it and submit it for processing. I dump it as a csv, which comes out as a csv (pipe delimeted values). The file is normally several hundred lines, one in awhile over 1000 (today’s was 1500).<\/p>\n
I am trying to write a PS script to read the file, make the changes and puke it back out, so i don’t have to go line by line, or even a search and replace in excel, to make the desired altercations in the file. The issue I run into is, each line is a total of 79 characters total, but for some reason, someone along the line must have inputted a value wrong (or maybe the system did it, not sure) and about half way through, it drops to 78 characters long. My script goes through and uses the substring method to parse values in each line and assign them to variables to create a new string line and save it to a new file. I discovered the location of the error, which is near the end of each line, near one of the values that I parse out. I am having trouble trying to come up with a solution for this. Right now its throwing an \" Exception calling “Substring” with “2” argument(s): “Index and length must refer to a location within the string. Parameter name: length” error message. Which i found is because of the irregular length of some of the lines, causing the substring length values, which are located at the end of each line, to be less than what is define for length in the substring, if that makes sense.<\/p>\n
So sample of a valid line is:
\n23|SPARROW Jack J |W32100 | | |SAGE | | |SAGE |X|X<\/p>\n
example of an invalid line:
\n23|SPARROW Jack J |W32100 | | |SAGE | | |SAGE|X|X<\/p>\n
notice the late of a space between the ‘E’ at the end of ‘SAGE’ and the proceeding pipe.<\/p>\n
Here is my code to parse values out of each line:<\/p>\n
Get-Content -Path \".\\InputFile.txt\" | ForEach-Object {\n \n $DistrictNum = $_.substring(0,2)\n \n $CaseNum = $_.substring(32,10) \n\n $OldOffice = $_.substring(43,3) \n \n $OldUnit = $_.substring(47,5)\n \n $OldWorker = $_.substring(53,5)\n \n $NewOffice = $_.substring(59,3)\n\n $NewUnit = $_.substring(63,5)\n \n $NewWorker = $_.substring(69,5)\n if ( ($NewWorker.EndsWith('\\|') ) ) {\n $NewWorker = $NewWorker.replace('\\|',' ')\n \n\n } \n $Tape = $_.substring(75,1)\n \n $Filler = $_.substring(77,1)\n\n\n $Dataline = $DistrictNum + $CaseNum + $OldOffice + $OldUnit + $OldWorker + $NewOffice + $NewUnit + $NewWorker + $Tape + $Filler \n $Dataline | Out-File -FilePath \"$PSScriptRoot\\OutputFile.txt\" -Append \n } | Out-Null\n<\/code><\/pre>\nI can’t seem to figure out how to get that extra space between the ‘E’ at the end of ‘SAGE’ and the proceeding pipe, to be able to push the invalid lines out from 78 characters to the needed 79. For some reason the replace method i am using is not working. It seems to read in the file then throw an error once it reads in the first instance of an invalid line.<\/p>","upvoteCount":4,"answerCount":15,"datePublished":"2025-06-10T20:27:03.670Z","author":{"@type":"Person","name":"SpiceAddict85","url":"https://community.spiceworks.com/u/SpiceAddict85"},"acceptedAnswer":{"@type":"Answer","text":"
This is one way to apply that schema:<\/p>\n
get-content .\\inputfile.txt | Foreach-Object {\n # split columns into an array using pipe delimiter\n $s = $_ -split '\\|'\n # district number\n $s[0] = $s[0].PadRight(2,' ').SubString(0,2)\n # case number\n $s[2] = $s[2].PadRight(10,' ').SubString(0,10)\n # old office\n $s[3] = $s[3].PadRight(3,' ').SubString(0,3)\n # old unit\n $s[4] = $s[4].PadRight(5,' ').SubString(0,5)\n # old worker\n $s[5] = $s[5].PadRight(5,' ').SubString(0,5)\n # new office\n $s[6] = $s[6].PadRight(3,' ').SubString(0,3) \n # new unit\n $s[7] = $s[7].PadRight(5,' ').SubString(0,5) \n # new worker\n $s[8] = $s[8].PadRight(5,' ').SubString(0,5)\n # extra X values\n $extra = 'XX'\n # combine array elements and extra values \n -join (@($s[0]) + $s[2..8] + $extra)\n} | Set-Content \"$PSScriptRoot\\OutputFile.txt\"\n<\/code><\/pre>\nOf course you can replace the variable names with something more descriptive and add all the elements together like you did in your code. You could also Import-Csv and add column names. But that does mean you will need PowerShell 7 to avoid quotes and remove the header line from the output.<\/p>","upvoteCount":0,"datePublished":"2025-06-11T17:29:28.882Z","url":"https://community.spiceworks.com/t/reading-in-a-file-issue/1214030/11","author":{"@type":"Person","name":"adminofthings","url":"https://community.spiceworks.com/u/adminofthings"}},"suggestedAnswer":[{"@type":"Answer","text":"
From time to time i get a request from a dept head to do a query in a DB and dump the results then alter it and submit it for processing. I dump it as a csv, which comes out as a csv (pipe delimeted values). The file is normally several hundred lines, one in awhile over 1000 (today’s was 1500).<\/p>\n
I am trying to write a PS script to read the file, make the changes and puke it back out, so i don’t have to go line by line, or even a search and replace in excel, to make the desired altercations in the file. The issue I run into is, each line is a total of 79 characters total, but for some reason, someone along the line must have inputted a value wrong (or maybe the system did it, not sure) and about half way through, it drops to 78 characters long. My script goes through and uses the substring method to parse values in each line and assign them to variables to create a new string line and save it to a new file. I discovered the location of the error, which is near the end of each line, near one of the values that I parse out. I am having trouble trying to come up with a solution for this. Right now its throwing an \" Exception calling “Substring” with “2” argument(s): “Index and length must refer to a location within the string. Parameter name: length” error message. Which i found is because of the irregular length of some of the lines, causing the substring length values, which are located at the end of each line, to be less than what is define for length in the substring, if that makes sense.<\/p>\n
So sample of a valid line is:
\n23|SPARROW Jack J |W32100 | | |SAGE | | |SAGE |X|X<\/p>\n
example of an invalid line:
\n23|SPARROW Jack J |W32100 | | |SAGE | | |SAGE|X|X<\/p>\n
notice the late of a space between the ‘E’ at the end of ‘SAGE’ and the proceeding pipe.<\/p>\n
Here is my code to parse values out of each line:<\/p>\n
Get-Content -Path \".\\InputFile.txt\" | ForEach-Object {\n \n $DistrictNum = $_.substring(0,2)\n \n $CaseNum = $_.substring(32,10) \n\n $OldOffice = $_.substring(43,3) \n \n $OldUnit = $_.substring(47,5)\n \n $OldWorker = $_.substring(53,5)\n \n $NewOffice = $_.substring(59,3)\n\n $NewUnit = $_.substring(63,5)\n \n $NewWorker = $_.substring(69,5)\n if ( ($NewWorker.EndsWith('\\|') ) ) {\n $NewWorker = $NewWorker.replace('\\|',' ')\n \n\n } \n $Tape = $_.substring(75,1)\n \n $Filler = $_.substring(77,1)\n\n\n $Dataline = $DistrictNum + $CaseNum + $OldOffice + $OldUnit + $OldWorker + $NewOffice + $NewUnit + $NewWorker + $Tape + $Filler \n $Dataline | Out-File -FilePath \"$PSScriptRoot\\OutputFile.txt\" -Append \n } | Out-Null\n<\/code><\/pre>\nI can’t seem to figure out how to get that extra space between the ‘E’ at the end of ‘SAGE’ and the proceeding pipe, to be able to push the invalid lines out from 78 characters to the needed 79. For some reason the replace method i am using is not working. It seems to read in the file then throw an error once it reads in the first instance of an invalid line.<\/p>","upvoteCount":4,"datePublished":"2025-06-10T20:27:03.747Z","url":"https://community.spiceworks.com/t/reading-in-a-file-issue/1214030/1","author":{"@type":"Person","name":"SpiceAddict85","url":"https://community.spiceworks.com/u/SpiceAddict85"}},{"@type":"Answer","text":"
I would use -split, -join, and -replace for this. Let’s say the column you want to modify is third from the last, you can do something like this:<\/p>\n
get-content .\\inputfile.txt | Foreach-Object {\n # split columns into an array using pipe delimiter\n $s = $_ -split '\\|'\n # replace the final character (if it is nonspace) of third to last item with the character plus a space\n $s[-3] = $s[-3] -replace '\\S$','$0 '\n # join items back together with pipe separators\n $s -join '|'\n} | Set-Content \"$PSScriptRoot\\OutputFile.txt\"\n<\/code><\/pre>","upvoteCount":1,"datePublished":"2025-06-10T20:43:22.286Z","url":"https://community.spiceworks.com/t/reading-in-a-file-issue/1214030/2","author":{"@type":"Person","name":"adminofthings","url":"https://community.spiceworks.com/u/adminofthings"}},{"@type":"Answer","text":"You can import it as a CSV ? just tell it to use ‘|’ as a delimiter?
\nand then you can trim the input, which will get rid of the space?<\/p>\n
import-csv \"somefile.txt\" -delimiter \"|\"\n<\/code><\/pre>\nmaybe I’m missing something?<\/p>","upvoteCount":1,"datePublished":"2025-06-10T20:44:50.715Z","url":"https://community.spiceworks.com/t/reading-in-a-file-issue/1214030/3","author":{"@type":"Person","name":"Neally","url":"https://community.spiceworks.com/u/Neally"}},{"@type":"Answer","text":"
I like Neally’s idea if you are using PowerShell 7. Then you can write back to the text file using Export-Csv -UseQuotes Never. Otherwise, you are dealing with quoted fields in your output. Or you are building your output using property member references rather than substrings. I’m not a fan of the substring stuff as it is overly brittle if checks aren’t in place.<\/p>","upvoteCount":2,"datePublished":"2025-06-10T20:49:25.019Z","url":"https://community.spiceworks.com/t/reading-in-a-file-issue/1214030/4","author":{"@type":"Person","name":"adminofthings","url":"https://community.spiceworks.com/u/adminofthings"}},{"@type":"Answer","text":"