2009-06-23 8 views
4

J'aimerais pouvoir taper des commandes simples et rapides qui manipulent les fichiers sur place. Par exemple:Powershell: comment lire et écrire des E/S dans un pipeline?

# prettify an XML file 
format-xml foo | out-file foo 

Cela ne fonctionnera pas car le pipeline est conçu pour être "gourmand". L'applet de commande en aval acquiert un verrou en écriture sur le fichier dès que l'applet de commande en amont traite la première ligne d'entrée, ce qui empêche la cmdlet en amont de lire le reste du fichier.

Il existe de nombreuses solutions possibles: écriture dans des fichiers temporaires, opérations séparées dans plusieurs pipelines (stockage des résultats intermédiaires dans des variables) ou similaires. Mais je me dis que c'est une tâche très courante pour laquelle quelqu'un a développé un raccourci rapide et facile à utiliser.

J'ai essayé ceci:

function Buffer-Object 
{ 
    [CmdletBinding()] 
    param (
     [parameter(Mandatory=$True, ValueFromPipeline=$True)] 
     [psobject] $InputObject 
    ) 

    begin { $buf = new-list psobject } 
    process { $buf.Add($InputObject) } 
    end { $buf } 
} 
format-xml foo | buffer-object | out-file foo 

Il fonctionne bien dans certaines situations. Couplé à un alias court et déployé dans une distribution commune comme PSCX, il serait «assez bon» pour des tâches interactives rapides. Malheureusement, il semble que certaines applets de commande (y compris hors fichier) saisissent le verrou dans leur méthode Begin {} plutôt que dans Process {}, ce qui ne résout pas cet exemple particulier.

Autres idées?

Répondre

7

Pour autant que je me souviens (ne peut pas tester maintenant), vous pouvez lire un fichier en mémoire avec la notation d'espace de noms:

${c:file1.txt} = ${c:file1.txt} -replace "a" "o" 
+0

Très cool! Je n'ai jamais vu cette syntaxe. Notez que pour l'exemple spécifique ci-dessus, vous devez utiliser des parenthèses autour du RHS de l'affectation: $ {c: foo} = ($ {c: foo} | format-xml). Ou vous pouvez utiliser un pipeline modifié: $ {c: foo} | format-xml | out-file foo –

+1

C'est la même syntaxe que celle utilisée pour accéder aux variables. Il existe une interface spéciale sur les fournisseurs pour prendre en charge cela, mais tous les fournisseurs ne l'implémentent pas. Donc, c'est vraiment comment vous accédez aux variables dans le fournisseur de variables. – JasonMArcher

Questions connexes