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"
}
}
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"
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
.
Get-ChildItem
vers Select-String
, comme indiqué dans réponse utile de Dave Sexton .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).-Encoding
; Par exemple, ... | Set-Content Output.txt -Encoding Utf8
.>
, l'opérateur de redirection de sortie toujours crée des fichiers UTF-16LE (un appel de codage PowerShell Unicode
), tout comme Out-File
par défaut (pouvant être modifié avec -Encoding
).>
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.
Output.txt
aurait réécrit dans son ensemble dans chaque itération de votre boucle foreach
.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
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