2013-03-11 17 views
5

Sto provando a scrivere uno script per cercare il contenuto di un file, e quando si incontra un gruppo di caratteri di controllo ASCII, per inserire un CR/LF.PowerShell: Trova/Sostituisci pattern di caratteri di controllo ASCII

Il modello di caratteri vorrei sostituire sono [ETX] [NUL] [STX] [ETX] [SOH]

 
    $filenames = @(Get-Childitem "E:\VendorFiles\*") 

    $CR = @("[char]3 [char]0 [char]2 [char]3 [char]1") 
    foreach ($file in $filenames) {$outfile = "$file" + ".txt" 
    Get-Content $file | Foreach-object { 
      $_ -replace $CR,"`r`n" ` 
      -replace [char]3,"|" ` 
      -replace [char]1,"{" ` 
      -replace "\\","\\" ` 
     } | Set-Content -encoding "UTF8" $outfile} 

risposta

6

Questa espressione:

@("[char]3 [char]0 [char]2 [char]3 [char]1") 

... crea una serie con un unico elemento. Sono necessarie delle virgole tra i termini se si desidera realmente una serie di 5 elementi, ma -replace non supporta comunque gli array. Inoltre, il tuo singolo elemento contiene i caratteri letterali digitati; non quello che ti aspettavi.

Quello che ti serve è creare una stringa semplice da alimentare a -replace; questo è un po 'più complicato quando si hanno a che fare con caratteri non stampabili. Si aveva l'idea giusta - devi solo dire a PowerShell per interpolare le espressioni di codice all'interno della vostra stringa utilizzando la notazione $() su ogni espressione:

$CR = "$([char]3)$([char]0)$([char]2)$([char]3)$([char]1)" 
+0

Ben fatto. Quibble: '-replace' non supporta gli array su _RHS_ (solo un _regex_ supportato); tuttavia, _LHS_ - la/e stringa/e di input - può essere una matrice (nel qual caso l'operazione di sostituzione viene eseguita singolarmente sugli elementi dell'array). – mklement0

0

Ho una funzione in uno script che fa qualcosa di simile . Non sono sicuro se questo vi aiuterà a:

# This function will make a new file that has custom comments 
# it will comment out "rollback tran" 
# it will uncomment out "--commit tran" 
function CommentAndUncomment($TheScript) 
{ 
    PrintTextAndTime("About to run this SQL file: $TheScript") 
    PrintTextAndTime("Will comment out 'rollback tran' and uncomment '--commit tran'") 
    $content = Get-Content $TheScript 
    $content | 
     ForEach-Object { 
     if ($_ -clike "*ROLLBACK TRAN;*") { 
      $_ -replace "ROLLBACK TRAN;", "--ROLLBACK TRAN;" 
     } 
     elseif ($_ -clike "*--COMMIT TRAN;*") { 
      $_ -replace "--COMMIT TRAN;", "COMMIT TRAN;" 
     } 
     else{ 
      $_ 
     } 
     } | 
     Set-Content $ModifiedCommentsFile 
    echo $ModifiedCommentsFile 
    sqlcmd -i $ModifiedCommentsFile 
    del $ModifiedCommentsFile 
} 
+0

Grazie, ma questo non ha aiutato. –

1

Michael Sorens' helpful answer spiega il problema con il vostro approccio bene e offre una soluzione di lavoro.

per offrire un'alternativa più semplice:

$CR = ([char[]] (3, 0, 2, 3, 1)) -join '' 
  • 3, 0, 2, 3, 1 crea un array di interi con i punti di codice Unicode dei personaggi per creare.

  • Cast [char[]] converte i punti di codice in caratteri reali ([char]).

  • -join '' unisce la matrice di caratteri (senza separatore) a per una singola stringa .

+1

Grazie, @ mkelement0, per il miglioramento! –