Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
174 views
in Technique[技术] by (71.8m points)

Changing a numerical value in a text file using PowerShell

Im looking for a solution that will allow me to modify numerical values(xyz values) in a line of text using the Get-Content cmdlet and write those vales back to the text file. I have a text file "MyFile.txt" with lines of text as follows"

    COMPONENT-IDENTIFIER    1
    ATTRIBUTE9    C
    ATTRIBUTE22   0
    END-POINT    518700.500    555700.500    33234.800    1    SL
    END-POINT    518500.500    555700.500    33234.800    1    SL
    WEIGHT    2.177
    UBV    {111256-254885-000-1515-BGL518FS7D}
    END-POINT    518700.500    555700.500    33234.800    1    PL
    END-POINT    518500.500    555700.500    33234.800    1    PL
    ATTRIBUTE15   D
    ATTRIBUTE08   3

Basically i need to find the -Pattern "END-POINT" and parse the line and change the numerical values for the first three double values and write it back to the text file (text file delimiters are odd - four spaces). I just need to perform basic math like add, subtract and or divide. The file is large and has multiple attributes and other values that i do not need to modify only the "END-POINT" values.

here is what i have, cant quiet figure out how to replace the values, im not sure if its even the right direction:

$MyFile = Get-Content "MyFile.txt"

ForEach ($line in $MyFile){
    if ($line | select-String -Pattern 'END-POINT'){
        $Array = @($line)
        $NewArray = $Array -split "    "
        $Arrayx = $NewArray.split(" ")[2]/12.0
        $Arrayy = $NewArray.split(" ")[2]/12.0
        $Arrayx = $NewArray.split(" ")[2]/12.0
    }
}

Appreciate any insight in advance.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In order to update these numeric END-POINT values, I'd suggest you use switch with option -Regex and loop through the file line-by-line:

$endPointRegex = '(?<endpoint>s*END-POINTs{4})(?<num1>d+(?:.d+))?s+(?<num2>d+(?:.d+))?s+(?<num3>d+(?:.d+))?(?<rest>.*)'
$result = switch -Regex -File 'D:TestMyFile.txt' {
    $endPointRegex {
        '{0}{1}   {2}    {3}{4}' -f $matches['endpoint'], 
                                    ([double]$matches['num1'] / 12.0), 
                                    ([double]$matches['num2'] / 12.0),
                                    ([double]$matches['num3'] / 12.0),
                                    $matches['rest']
    }
    default { $_ }
}

# output on screen
$result

# output to new file
$result | Set-Content -Path 'D:TestMyNewFile.txt' -Force

Output:

    COMPONENT-IDENTIFIER    1
    ATTRIBUTE9    C
    ATTRIBUTE22   0
    END-POINT    43225.0416666667   46308.375    2769.56666666667    1    SL
    END-POINT    43208.375   46308.375    2769.56666666667    1    SL
    WEIGHT    2.177
    UBV    {111256-254885-000-1515-BGL518FS7D}
    END-POINT    43225.0416666667   46308.375    2769.56666666667    1    PL
    END-POINT    43208.375   46308.375    2769.56666666667    1    PL
    ATTRIBUTE15   D
    ATTRIBUTE08   3

If you want the numbers devided by 12.0 also have 3 decimals like the original values, change to:

$endPointRegex = '(?<endpoint>s*END-POINTs{4})(?<num1>d+(?:.d+))?s+(?<num2>d+(?:.d+))?s+(?<num3>d+(?:.d+))?(?<rest>.*)'
$result = switch -Regex -File 'D:TestMyFile.txt' {
    $endPointRegex {
        '{0}{1:F3}   {2:F3}    {3:F3}{4}' -f $matches['endpoint'], 
                                             ([double]$matches['num1'] / 12.0), 
                                             ([double]$matches['num2'] / 12.0),
                                             ([double]$matches['num3'] / 12.0),
                                             $matches['rest']
    }
    default { $_ }
}

# output on screen
$result

# output to new file
$result | Set-Content -Path 'D:TestMyNewFile.txt' -Force

Output:

    COMPONENT-IDENTIFIER    1
    ATTRIBUTE9    C
    ATTRIBUTE22   0
    END-POINT    43225.042   46308.375    2769.567    1    SL
    END-POINT    43208.375   46308.375    2769.567    1    SL
    WEIGHT    2.177
    UBV    {111256-254885-000-1515-BGL518FS7D}
    END-POINT    43225.042   46308.375    2769.567    1    PL
    END-POINT    43208.375   46308.375    2769.567    1    PL
    ATTRIBUTE15   D
    ATTRIBUTE08   3

Regex details:

(?<endpoint>        Match the regular expression below and capture its match into backreference with name “endpoint”
   s               Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
      *             Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
   END-POINT        Match the characters “END-POINT” literally
   s               Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
      {4}           Exactly 4 times
)                  
(?<num1>            Match the regular expression below and capture its match into backreference with name “num1”
   d               Match a single digit 0..9
      +             Between one and unlimited times, as many times as possible, giving back as needed (greedy)
   (?:              Match the regular expression below
      .            Match the character “.” literally
      d            Match a single digit 0..9
         +          Between one and unlimited times, as many times as possible, giving back as needed (greedy)
   )               
)?                  Between zero and one times, as many times as possible, giving back as needed (greedy)
s                  Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
   +                Between one and unlimited times, as many times as possible, giving back as needed (greedy)
(?<num2>            Match the regular expression below and capture its match into backreference with name “num2”
   d               Match a single digit 0..9
      +             Between one and unlimited times, as many times as possible, giving back as needed (greedy)
   (?:              Match the regular expression below
      .            Match the character “.” literally
      d            Match a single digit 0..9
         +          Between one and unlimited times, as many times as possible, giving back as needed (greedy)
   )               
)?                  Between zero and one times, as many times as possible, giving back as needed (greedy)
s                  Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
   +                Between one and unlimited times, as many times as possible, giving back as needed (greedy)
(?<num3>            Match the regular expression below and capture its match into backreference with name “num3”
   d               Match a single digit 0..9
      +             Between one and unlimited times, as many times as possible, giving back as needed (greedy)
   (?:              Match the regular expression below
      .            Match the character “.” literally
      d            Match a single digit 0..9
         +          Between one and unlimited times, as many times as possible, giving back as needed (greedy)
   )               
)?                  Between zero and one times, as many times as possible, giving back as needed (greedy)
(?<rest>            Match the regular expression below and capture its match into backreference with name “rest”
   .                Match any single character that is not a line break character
      *             Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
)

Mind you, these numbers will format with decimal comma's if you are in a country that uses the decimal comma instead of a decimal point. Since you're in Houston, you won't have to deal with that


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...