web-dev-qa-db-fra.com

Extraire les lignes correspondant à un motif de tous les fichiers texte d'un dossier dans un seul fichier de sortie

J'essaie d'extraire chaque ligne en commençant par "%%" dans tous les fichiers d'un dossier, puis de les copier dans un fichier texte séparé. J'utilise actuellement ce code dans le code PowerShell, mais je n'obtiens aucun résultat. 

$files = Get-ChildItem "folder" -Filter *.txt
foreach ($file in $files)
{
if ($_ -like "*%%*")
{
Set-Content "Output.txt" 
}  
}
6
Jabir Jamal

Je pense que la suggestion de mklement0 d'utiliser Select-String est la voie à suivre. En ajoutant à sa réponse, vous pouvez diriger la sortie de Get-ChildItem dans le Select-String afin que l'ensemble du processus devienne une doublure Powershell. 

Quelque chose comme ça:

Get-ChildItem "folder" -Filter *.txt | Select-String -Pattern '^%%' | Select -ExpandProperty line | Set-Content "Output.txt"
12
Dave Sexton

La cmdlet Select-String offre une solution beaucoup plus simple (syntaxe PSv3 +):

(Select-String -Path folder\*.txt -Pattern '^%%').Line | Set-Content Output.txt
  • Select-String accepte un modèle nom_fichier/chemin d'accès via son paramètre -Path. Ainsi, dans ce cas simple, il n'est pas nécessaire d'utiliser Get-ChildItem.

    • Si, au contraire, votre sélection de fichier est récursive ou utilise des critères plus complexes, vous pouvez rediriger la sortie de Get-ChildItem vers Select-String, comme indiqué dans réponse utile de Dave Sexton .
    • Notez que, selon la documentation _, Select-String suppose par défaut que les fichiers d'entrée sont codés en UTF-8, mais vous pouvez le modifier avec le paramètre -Encoding; considérez également le codage output décrit ci-dessous.
  • Le paramètre Select-String de -Pattern attend une expression régulière plutôt qu'une expression générique.
    ^%% ne correspond au littéral %% qu'au début (^) d'une ligne.

  • Select-String génère [Microsoft.PowerShell.Commands.MatchInfo]objets contenant des informations sur chaque correspondance; La propriété .Line de chaque objet contient le texte intégral d'une ligne d'entrée correspondante.

  • Set-Content Output.txt envoie toutes les lignes correspondantes dans un fichier de sortie unique Output.txt

    • Set-Content utilise la page de codes Windows héritée du système (codage sur un octet sur 8 bits - même si la documentation prétend à tort que des fichiers ASCII sont produits).
      Si vous souhaitez contrôler le codage de sortie de manière explicite, utilisez le paramètre -Encoding; Par exemple, ... | Set-Content Output.txt -Encoding Utf8.
    • En revanche, >, l'opérateur de redirection de sortie toujours crée des fichiers UTF-16LE (un appel de codage PowerShell Unicode), tout comme Out-Filepar défaut (pouvant être modifié avec -Encoding).
      Notez également que >Out-File applique la mise en forme par défaut de PowerShell aux objets d'entrée pour obtenir la représentation sous forme de chaîne à écrire dans le fichier de sortie, alors que Set-Content traite l'entrée comme chaînes (appelle .ToString() sur les objets d'entrée, si nécessaire). . Dans le cas présent, comme tous les objets en entrée sont déjà des chaînes, il n'y a pas de différence (sauf potentiellement pour l'encodage de caractères).

En ce qui concerne _/ce que vous avez essayé:

  • $_ dans votre foreach ($file in $files) fait référence à un fichier (un objet [System.IO.FileInfo]), vous évaluez donc votre expression générique *%%* par rapport au nom du fichier d'entrée plutôt que son contenu.

  • En dehors de cela, le modèle générique *%%* correspond à %%n'importe où dans la chaîne d'entrée, pas seulement à sa début (vous devrez utiliser %%* à la place).

  • L'appel Set-Content "Output.txt" est manquant input, car il ne fait pas partie d'un pipeline et, en l'absence d'entrée dans le pipeline, aucun argument -Value n'a été transmis.

    • Cependant, même si vous fournissiez une entrée, le fichier de sortie Output.txt aurait réécrit dans son ensemble dans chaque itération de votre boucle foreach.
7
mklement0
ls *.txt | %{
$f = $_
  gc $f.fullname | {
     if($_.StartWith("%%") -eq 1){
        $_ >> Output.txt
     }#end if
  }#end gc
}#end ls

Alias

ls - Get-ChildItem
gc - Get-Content
% - ForEach
$_ - Iterator variable for loop
>> - Redirection construct
# - Comment

http://ss64.com/ps/

1
Shantanu Gupta

Vous devez d'abord utiliser 

Obtenir du contenu

afin d'obtenir le contenu du fichier. Ensuite, vous faites la correspondance de chaîne et, sur cette base, vous restez définissez le contenu dans le fichier. Utilisez get-content et mettez une autre boucle à l'intérieur du foreach pour itérer toutes les lignes du fichier.

J'espère que cette logique vous aide

0
Ranadip Dutta