Home > Enterprise >  Appending text based on first char in each line of text within the file
Appending text based on first char in each line of text within the file

Time:02-26

I have a text file that needs manipulating. Example data in the text file looks like--

C02324R
C02645R
F06487R
F05564R
S09687R
J03345R

Here is what needs to happen--

  1. Go thru each line in the text file
  2. If first Char is 'C', append/add a '3' to the end of the line of text.
  3. If first chars are 'S0' append/add a '4' to the end of the line of text.
  4. If first chars are 'S1' append/add a '5' to the end of the line of text.
  5. If first char is 'F' append/add a '5' to the end of the line of text.
  6. If first char is 'J' append/add a '6' to the end of the line of text.

thus, the end result data would look like--

C02324R3
C02645R3
F06487R5
F05564R5
S09687R5
J03345R6

I can easily write this in vba excel, but I'm much more inexperienced at powershell. I've tried switch, foreach and case statements, mostly from borrowed code but can't seem to make it work. Here is one way I tried it--

switch -file 'C:\MyFile.txt'
    {
        $_.StartsWith("C")  {$_    "3"}
        $_.StartsWith("S0")  {$_   "4"}
        $_.StartsWith("S1")  {$_    "5"}
        $_.StartsWith("J")  {$_    "6"}
    }
    $data | Set-Content C:\MyFile.txt -Force*

Suggestions?

CodePudding user response:

To make this work with arbitrary expressions (like calling StartsWith()) as case predicates, you need to enclose the expression in a scriptblock:

$data = switch -file 'C:\MyFile.txt'
{
    {$_.StartsWith("C")}  {$_   "3"}
    {$_.StartsWith("S0")} {$_   "4"}
    {$_.StartsWith("S1")} {$_   "5"}
    {$_.StartsWith("J")}  {$_   "6"}
}

As an alternative, I would personally recommend using the -wildcard mode option instead:

$data = switch -wildcard -file 'C:\MyFile.txt'
{
    "C*"  {$_   "3"}
    "S0*" {$_   "4"}
    "S1*" {$_   "5"}
    "J*"  {$_   "6"}
}

Much easier to read :)


As Theo kindly pointed out, you might want to add a default case to let non-matching strings pass through as-is (use the bareword label default, no {} regardless of mode):

$data = switch -wildcard -file 'C:\MyFile.txt'
{
    "C*"  {$_   "3"}
    "S0*" {$_   "4"}
    "S1*" {$_   "5"}
    "J*"  {$_   "6"}
    default { $_ }
}

CodePudding user response:

@bill66man - welcome to stack overflow. Building on Theo's work, this script will generate the output in your example (your switch was missing the 'f' case) (I changed the filenames)

$dataset = switch -wildcard -file '.\MyFile.txt'
{
    "C*"  {$_   "3"}
    "S0*" {$_   "4"}
    "S1*" {$_   "5"}
    "F"    {$_   "5"}
    "J*"  {$_   "6"}
    default { $_ }
}

$dataset | Out-File -FilePath 'outfile.txt' -Force
  • Related