Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell 在生成的文本文件中设置特定行的格式_Powershell_String Formatting - Fatal编程技术网

Powershell 在生成的文本文件中设置特定行的格式

Powershell 在生成的文本文件中设置特定行的格式,powershell,string-formatting,Powershell,String Formatting,我想格式化使用Powershell生成的.st(文本)文件中的特定行 加载文本片段以供演示使用($TemplateSnippetText) 替换一些文本 将文本行与“:=”对齐,以便所有“:=”都在一行中(作为$TemplateSnippetText) 我正在努力形成,可能是一道数学题。。。? 这可以用String.Format(“{0,6}{1,15})方法完成吗 所需输出 diMoveStep_TFRX := 1;

我想格式化使用Powershell生成的.st(文本)文件中的特定行

  • 加载文本片段以供演示使用($TemplateSnippetText)
  • 替换一些文本
  • 将文本行与“:=”对齐,以便所有“:=”都在一行中(作为$TemplateSnippetText)
  • 我正在努力形成,可能是一道数学题。。。? 这可以用String.Format(“{0,6}{1,15})方法完成吗

    所需输出

                diMoveStep_TFRX                         := 1;
            ELSE // Bewegung vorbereiten
                diMoveStep_TFRX                         := 0;
            END_IF
        END_IF
    
        // Schrittkette Bewegung
        CASE diMoveStep_TFRX OF
            0:  // Bewegung vorbereiten
                fbAxis_TFRX.i_stCmd.xMoveAbsolute       := FALSE;
                diMoveStep_TFRX                         := 1;
            1:  // Bewegung starten
                IF stPos.stTFRX.stPickPos1.xEnMove  THEN
                    fbAxis_TFRX.i_stPar.stMove          := stMovePar_TFRX;
                    fbAxis_TFRX.i_stPar.lrPosition      := stDataProduct.stTFRX.lrPos_PickPos1;
                    strPickPos1_TFRX                    := 'PickPos1';
                    fbAxis_TFRX.i_stCmd.xMoveAbsolute   := TRUE;
                    diMoveStep_TFRX                     := 2;
                END_IF
            2:  // Bewegung ist gestartet
    
            IF NOT fbAxis_TFRX.i_stCmd.xMoveAbsolute THEN   // Bewegung starten
                diMoveStep_TFRX                     := 1;
            ELSE // Bewegung vorbereiten
                diMoveStep_TFRX                     := 0;
            END_IF
        END_IF
    
        // Schrittkette Bewegung
        CASE diMoveStep_TFRX OF
            0:  // Bewegung vorbereiten
                fbAxis_TFRX.i_stCmd.xMoveAbsolute       := FALSE;
                diMoveStep_TFRX                     := 1;
            1:  // Bewegung starten
                IF stPos.stTFRX.stPickPos1.xEnMove  THEN
                    fbAxis_TFRX.i_stPar.stMove          := stMovePar_TFRX;
                    fbAxis_TFRX.i_stPar.lrPosition      := stDataProduct.stTFRX.lrPos_PickPos1;
                    strPickPos1_TFRX                        := 'PickPos1';
                    fbAxis_TFRX.i_stCmd.xMoveAbsolute   := TRUE;
                    diMoveStep_TFRX                     := 2;
                END_IF
            2:  // Bewegung ist gestartet
    
    实际产出

                diMoveStep_TFRX                         := 1;
            ELSE // Bewegung vorbereiten
                diMoveStep_TFRX                         := 0;
            END_IF
        END_IF
    
        // Schrittkette Bewegung
        CASE diMoveStep_TFRX OF
            0:  // Bewegung vorbereiten
                fbAxis_TFRX.i_stCmd.xMoveAbsolute       := FALSE;
                diMoveStep_TFRX                         := 1;
            1:  // Bewegung starten
                IF stPos.stTFRX.stPickPos1.xEnMove  THEN
                    fbAxis_TFRX.i_stPar.stMove          := stMovePar_TFRX;
                    fbAxis_TFRX.i_stPar.lrPosition      := stDataProduct.stTFRX.lrPos_PickPos1;
                    strPickPos1_TFRX                    := 'PickPos1';
                    fbAxis_TFRX.i_stCmd.xMoveAbsolute   := TRUE;
                    diMoveStep_TFRX                     := 2;
                END_IF
            2:  // Bewegung ist gestartet
    
            IF NOT fbAxis_TFRX.i_stCmd.xMoveAbsolute THEN   // Bewegung starten
                diMoveStep_TFRX                     := 1;
            ELSE // Bewegung vorbereiten
                diMoveStep_TFRX                     := 0;
            END_IF
        END_IF
    
        // Schrittkette Bewegung
        CASE diMoveStep_TFRX OF
            0:  // Bewegung vorbereiten
                fbAxis_TFRX.i_stCmd.xMoveAbsolute       := FALSE;
                diMoveStep_TFRX                     := 1;
            1:  // Bewegung starten
                IF stPos.stTFRX.stPickPos1.xEnMove  THEN
                    fbAxis_TFRX.i_stPar.stMove          := stMovePar_TFRX;
                    fbAxis_TFRX.i_stPar.lrPosition      := stDataProduct.stTFRX.lrPos_PickPos1;
                    strPickPos1_TFRX                        := 'PickPos1';
                    fbAxis_TFRX.i_stCmd.xMoveAbsolute   := TRUE;
                    diMoveStep_TFRX                     := 2;
                END_IF
            2:  // Bewegung ist gestartet
    
    完整的Powershell 5.1代码:

    $TemplateSnippetText = 
    "ACTION ActAuto_Move_AXISNAME_TARGETPOS: // COMMENT
        // Rücksetzen
        IF NOT stStep.xEntryDone THEN
            IF NOT fbAxis_AXISNAME.i_stCmd.xMoveAbsolute THEN   // Bewegung starten
                diMoveStep_AXISNAME                             := 1;
            ELSE // Bewegung vorbereiten
                diMoveStep_AXISNAME                             := 0;
            END_IF
        END_IF
    
        // Schrittkette Bewegung
        CASE diMoveStep_AXISNAME OF
            0:  // Bewegung vorbereiten
                fbAxis_AXISNAME.i_stCmd.xMoveAbsolute           := FALSE;
                diMoveStep_AXISNAME                             := 1;
            1:  // Bewegung starten
                IF stPos.stAXISNAME.stTARGETPOS.xEnMove THEN
                    fbAxis_AXISNAME.i_stPar.stMove              := stMovePar_AXISNAME;
                    fbAxis_AXISNAME.i_stPar.lrPosition          := stDataProduct.stAXISNAME.lrPos_TARGETPOS;
                    strTargetPos_AXISNAME                       := 'TARGETPOS';
                    fbAxis_AXISNAME.i_stCmd.xMoveAbsolute       := TRUE;
                    diMoveStep_AXISNAME                         := 2;
                END_IF
            2:  // Bewegung ist gestartet
                IF fbAxis_AXISNAME.q_stStat.xMoveDone AND
                    stPos.stAXISNAME.stTARGETPOS.xInRange THEN
                    fbAxis_AXISNAME.i_stCmd.xMoveAbsolute       := FALSE;
                    stStep.xActDone                             := TRUE;
                    diMoveStep_AXISNAME                         := 3;
                END_IF
            3:  // Bewegung ist beStringEndt 
                ;
        END_CASE
        
        // Stop deaktivieren während der Bewegung
        stStep.enStopMode                                       := SEL(fbAxis_AXISNAME.i_stCmd.xMoveAbsolute, EnableStop, DisableStop);
    END_ACTION
    
    "
    #Dateipfad
    $strFilePath = 'C:\Temp\CodeSnippet.st' 
    $RegPatRepWhiteSpaces = '\s+?(?=:=)'    # https://regex101.com/r/IEiymN/1
    $RegPatStartOfString = '^.*?(?=:=)'     # https://regex101.com/r/icJGAy/1
    $RegPatEndOfString  = ':=(.*)'          # https://regex101.com/r/0UlzT7/1
    
    
    # File-Inhalt löschen
    Remove-Item $strFilePath  -Include *.st
    
    $SnippetsToGenerate = @(
        [PSCustomObject]@{COMMENT = 'Zielposition1'; AXISNAME = 'TFRX'; TARGETPOS = 'PickPos1' }
       # [PSCustomObject]@{COMMENT = 'Zielposition2'; AXISNAME = 'TFRX'; TARGETPOS = 'PickPos2' }
        #[PSCustomObject]@{COMMENT = 'Zielposition3'; AXISNAME = 'TFRX'; TARGETPOS = 'PickPos3' }
    )
    
    $SnippetsToGenerate | ForEach-Object {
    $CurrentSnippet = $TemplateSnippetText
    $CurrentSnippet = $CurrentSnippet -replace "COMMENT", $_.COMMENT -replace "AXISNAME", $_.AXISNAME -replace "TARGETPOS", $_.TARGETPOS
    $CurrentSnippet | Out-File -FilePath $strFilePath -Append 
    } 
    
        (Get-Content -Path $strFilePath -Raw) -Replace $RegPatRepWhiteSpaces,'' | Set-Content -Path $strFilePath
        
        $IndexOfAllocation = Get-Content -Path $strFilePath | ForEach-Object {$_.IndexOf(":=") } | Measure-Object -Maximum
        
        (Get-Content -Path $strFilePath) | ForEach-Object {
                $currentObject = $_
                if($currentObject -match ':='){   
                    $StringStart = [Regex]::Matches($currentObject, $RegPatStartOfString).Value 
                    $StringEnd = [Regex]::Matches($currentObject, $RegPatEndOfString ).Value
    
                    Write-Host "Lenght StringStart" $StringStart.Length"Lenght StringEnd" $StringEnd.Length
                    Write-host "Max" $IndexOfAllocation.Maximum
    
                    [uint32]$DiffToPaddAbsolute = ($IndexOfAllocation.Maximum  - $StringStart.Length)
            
                    #if (($DiffToPaddAbsolute % 4) -gt 2) {
                        $DiffToPaddAbsoluteTabs = [math]::Ceiling($DiffToPaddAbsolute / 4) + 1
                    #   } else {
                        #$DiffToPaddAbsoluteTabs = [math]::Floor($DiffToPaddAbsolute / 4) + 1
                    #}
                    $StringStartPadded= $StringStart.PadRight($StringStart.Length + $DiffToPaddAbsoluteTabs,[char]9)
                    $currentObject = "$StringStartPadded$StringEnd"
                    }
                $currentObject
        } | Set-Content  -Path $strFilePath
    Invoke-Item $strFilePath
    

    我认为您可能使填充过于复杂-根本不需要正则表达式,我们只需要找到初始替换后每行中出现的偏移量
    :=

    $FilePath = "C:\Temp\CodeSnippet.st"
    $TemplateSnippetText = "<Insert Your Template Here>"
    
    $SnippetsToGenerate = @(
      [PSCustomObject]@{COMMENT = 'Zielposition1'; AXISNAME = 'TFRX'; TARGETPOS = 'PickPos1' }
      [PSCustomObject]@{COMMENT = 'Zielposition2'; AXISNAME = 'TFRX'; TARGETPOS = 'PickPos2' }
      [PSCustomObject]@{COMMENT = 'Zielposition3'; AXISNAME = 'TFRX'; TARGETPOS = 'PickPos3' }
    )
    
    $SnippetsToGenerate | ForEach-Object {
      # Use `-creplace` (Case-sensitive replace)
      $snippet = $TemplateSnippetText -creplace 'COMMENT', $_.COMMENT -creplace 'AXISNAME', $_.AXISNAME -creplace 'TARGETPOS', $_.TARGETPOS
    
      # Split into individual lines
      $lines = $snippet -split '\r?\n'
      
      # Use String.IndexOf() to find the current column offset of `:=` in each line
      $offsets = $lines | ForEach-Object IndexOf ':='
      
      # Sort the offsets to find the right-most occurrence (we will align everything to this one)
      $targetOffset = $offsets | Sort-Object -Descending | Select-Object -First 1
      
      for ($i = 0; $i -lt $lines.Count; $i++) {
        $line = $lines[$i]
        $offset = $offsets[$i]
      
        if ($offset -in 0..$targetOffset) {
          # $offset is > -1, so we know the line contains a `:=`, let's left-pad it by 
          # inserting the required number of spaces at the position right in front of `:=`
          $lines[$i] = $line.Insert($offset, [string]::new(" ", $targetOffset - $offset))
        }
      }
    
      # Output 
      $lines
    } |Set-Content $FilePath
    
    如果要保留原始偏移量,只需基于模板计算
    $targetOffset
    ,无需进行任何替换,然后再生成实际片段:

    $targetOffset = $TemplateSnippetText -replace '\r?\n' |ForEach-Object IndexOf := |Sort-Object -Descending |Select-Object -First 1
    
    $SnippetsToGenerate | ForEach-Object {
       # ...
    

    再次感谢Mathias帮我解决这个问题。我还需要做一些改变:

    $FilePath = "C:\Temp\CodeSnippet.st"
    $RegPatRepWhiteSpaces = '\s+?(?=:=)'    # https://regex101.com/r/IEiymN/1
    [uint16]$SpacesPerTab = 4
    $SpacesPerTabAsString = [string]::new([char]32, $SpacesPerTab)
    $TemplateSnippetText = 
    "
    ACTION Svd_NAME : // Schutzverdeck: COMMENT
        stHw.stBasic.stSvd_AXISNAME.stIn.xProtCircleIsClosedAndLocked   := xReplaceMe;
        stHw.stBasic.stSvd_AXISNAME.stIn.xAreaRdyForSvd             := xRepalaceMe;
        fbSvd_AXISNAME.i_stIoMap                                    := stHw.stBasic.stSvd_AXISNAME.stIn; 
        fbSvd_AXISNAME.i_udiVisu                                        := ADR(stVisu.stBasic.stSvd_AXISNAME); 
        fbSvd_AXISNAME();
        stHw.stBasic.stSvd_AXISNAMEstOut                        := fbSvd_AXISNAME.q_stIoMap;
        xReplaceMe                                                      := fbSvd_AXISNAME.q_stStat.xRequest;
    END_ACTION
    "
    
    $SnippetsToGenerate = @(
      [PSCustomObject]@{COMMENT = 'ZielpositionMitEinerLaenge'; AXISNAME = 'LangeraAcnName'; TARGETPOS = 'PickPos1' }
      [PSCustomObject]@{COMMENT = 'Zielposition2'; AXISNAME = 'EinNochViiisiiiiiiiiiiiiiielLaengereAchsenName'; TARGETPOS = 'PickPos2' }
      [PSCustomObject]@{COMMENT = 'Zielposidaassdtion3'; AXISNAME = 'TFRaaassdX'; TARGETPOS = 'PicdkPos3' }
    )
    
    $SnippetsToGenerate | ForEach-Object {
      # Use `-creplace` (Case-sensitive replace)
      $snippet = $TemplateSnippetText -creplace 'COMMENT', $_.COMMENT -creplace 'AXISNAME', $_.AXISNAME -creplace 'TARGETPOS', $_.TARGETPOS 
    
      # Replace all Tabs with Spaces to keep calculation simple
      $snippet =  $snippet -replace [char]9, $SpacesPerTabAsString -replace $RegPatRepWhiteSpaces, ''
    
      # Split into individual lines
      $lines = $snippet -split '\r?\n'
      
      # Use String.IndexOf() to find the current column offset of `:=` in each line
      $offsets = $lines | ForEach-Object IndexOf ':='
      
      # Sort the offsets to find the right-most occurrence (we will align everything to this one)
      $targetOffset = $offsets | Sort-Object -Descending | Select-Object -First 1
    
      # Round the offset to the next number divisible by SpacesPerTab, then add one more tab
      $targetOffset += ($targetOffset % $SpacesPerTab) + $SpacesPerTab
    
      for ($i = 0; $i -lt $lines.Count; $i++) {
        $line = $lines[$i]
        $offset = $offsets[$i]
    
        # $offset is > -1, so we know the line contains a `:=`
        if ($offset -in 0..$targetOffset) {
    
            # Calculate the number of Spaces that we want to insert
            $SpacesToInsert = ($targetOffset - $offset) % $SpacesPerTab
    
            # Calculate the number of Tabs that we want to insert (after filling with Spaces)
            $TabsToInsert = ($targetOffset - $offset - $SpacesToInsert) / $SpacesPerTab
    
            # First inserting the required number of spaces at the position right in front of `:=` and after fill up with Tabs
            $lines[$i] = $line.Insert($offset, [string]::new(" ", $SpacesToInsert)).Insert($offset + $SpacesToInsert, [string]::new([char]9, $TabsToInsert ))
          }
      }
      # Output, Replace all Groups of Spaces with Tabs
      $lines -replace  $SpacesPerTabAsString, [char]9  
    } |Set-Content $FilePath
    
    Invoke-Item "C:\Temp\CodeSnippet.st"
    

    如果您提供示例输入和所需输出,将帮助我们。simliar是我的第一种方法。但是结构化文本文件似乎是另一种编码的文件。\t 4\s。我如何处理它?@Txitxarro我恐怕不明白您的意思,您可以使用示例吗?VS代码设置:渲染空白选择是«all»。如果我在VSC中打开一个最初使用«b&r automation studio»创建的.st文件,则选项卡不是4个空格,而是“->”变量$TemplateSnippetText中的字符串,我最初从Powershell文件中的.st文件复制的字符串也是->(\t)但您的解决方案中的字符串仅包含空格。但无论如何,将以下内容添加到您的解决方案中可以做到这一点:#输出$lines-替换“”,[char]9-替换“+?(?=:=)’,“非常感谢。我将在星期一对它进行全面测试,然后给你feedback@Txitxarro啊,这很有道理。很高兴听到你解决了问题,不客气!:-)