扫描 txt 文件中的多个字符串并保存以下行
Scan txt file for multiple strings and save the following lines
我有一个问题想解决,但是,由于我不具备 PowerShell 知识,事实证明它比我希望的要难。所以任何帮助将不胜感激。
问题可以简化为:
在 txt 文件中查找字符串
提取该字符串后行的信息
将信息存储在句柄中
在 txt 文件中找到第二个字符串并重复该过程
将两个字符串都存储在一个新文件中或删除 txt 文件中的所有其他内容。
然后我尝试对大约 20k 个文件执行此操作。我希望在他们的关键字和逗号分隔下有信息,以便我可以将它们导入其他系统。
我的文件看起来有点像下面这样
random words
that are unimportant
Keyword
FirstlineofNumbersthatIwanttoExtract
random words again that are unimportant
Secondkeyword
SecondLineOfNumbersThatIWantToExtract
end of the file
然而,就我要提取的行所在的行而言,所有文件都不相似。我希望输出类似于
Keyword, SecondKeyword
FirstLineOfNumbersThatIWantToExtract, SecondLineOfNumbersThatIWantToExtract
完成了。我走到这一步
[System.IO.DirectoryInfo]$folder = 'C:\users\xx\Desktop\mappcent3'
foreach ($file in ($folder.EnumerateFiles())) {
if ($file.Extension -eq '.txt') {
$content = Get-Content $file
$FirstRegex = 'KeyWordOne
(.+)$'
$First_output = ""
$test = Select-String -Path $file.FullName -Pattern $FirstRegex
}
}
这将执行类似于您所要求的操作。这需要 PowerShell 3.0+
$path = 'C:\users\xx\Desktop\mappcent3'
$firstKeyword = "Keyword"
$secondKeyword = "Secondkeyword"
$resultsPath = "C:\Temp\results.csv"
Get-ChildItem $path -Filter "*.txt" | ForEach-Object{
# Read the file in
$fileContents = Get-Content $_.FullName
# Find the first keyword data
$firstKeywordData = ($fileContents | Select-String -Pattern $firstKeyword -Context 0,1 -SimpleMatch).Context.PostContext[0]
# Find the second keyword data
$secondKeywordData = ($fileContents | Select-String -Pattern $secondKeyword -Context 0,1 -SimpleMatch).Context.PostContext[0]
# Create a new object with details gathered.
[pscustomobject][ordered]@{
File = $_.FullName
FirstKeywordData = $firstKeywordData
SecondKeywordData = $secondKeywordData
}
} | Export-CSV $resultsPath -NoTypeInformation
Select-String
是这里最神奇的地方。我们利用 -Context
消耗匹配前后的行。我们想要下面的一个,所以这就是我们使用 0,1
的原因。将其包装在自定义对象中,然后我们可以将其导出到 CSV 文件。
关键字重叠
请注意,您的关键字可能会重叠并在输出文件中产生奇怪的结果。在您的示例中,关键字匹配多行,因此结果集会反映出来。
如果您只是想写回原始文件,您也可以轻松地做到这一点
"$firstKeywordData,$secondKeywordData" | Set-Content $_.FullName
或类似的东西。
Select-String
cmdlet 有一个 -Context
参数,可以轻松提取匹配行之前或之后的行。
您可以使用 Export-Csv
导出您需要的格式(尽管对于 20K 的文件您可能希望直接写入输出文件)
foreach($file in Get-ChildItem C:\users\xx\Desktop\mappcent3 |Where {-not $_.PsIsContainer})
{
$FirstKeyword = 'FirstKeyword'
$FirstLine = Select-String -Path $file.FullName -Pattern $FirstKeyword -Context 0,1 |Select -Expand Context -First 1 |Select -Expand PostContext
$SecondKeyword = 'SecondKeyword'
$SecondLine = Select-String -Path $file.FullName -Pattern $SecondKeyword -Context 0,1 |Select -Expand Context -First 1 |Select -Expand PostContext
New-Object psobject -Property @{$FirstKeyword=$FirstLine;$SecondKeyword=$SecondLine} |Export-Csv (Join-Path $file.DirectoryName ($file.BaseName + '_keywords.txt'))
}
我有一个问题想解决,但是,由于我不具备 PowerShell 知识,事实证明它比我希望的要难。所以任何帮助将不胜感激。
问题可以简化为:
在 txt 文件中查找字符串
提取该字符串后行的信息
将信息存储在句柄中
在 txt 文件中找到第二个字符串并重复该过程
将两个字符串都存储在一个新文件中或删除 txt 文件中的所有其他内容。
然后我尝试对大约 20k 个文件执行此操作。我希望在他们的关键字和逗号分隔下有信息,以便我可以将它们导入其他系统。
我的文件看起来有点像下面这样
random words
that are unimportant
Keyword
FirstlineofNumbersthatIwanttoExtract
random words again that are unimportant
Secondkeyword
SecondLineOfNumbersThatIWantToExtract
end of the file
然而,就我要提取的行所在的行而言,所有文件都不相似。我希望输出类似于
Keyword, SecondKeyword
FirstLineOfNumbersThatIWantToExtract, SecondLineOfNumbersThatIWantToExtract
完成了。我走到这一步
[System.IO.DirectoryInfo]$folder = 'C:\users\xx\Desktop\mappcent3'
foreach ($file in ($folder.EnumerateFiles())) {
if ($file.Extension -eq '.txt') {
$content = Get-Content $file
$FirstRegex = 'KeyWordOne
(.+)$'
$First_output = ""
$test = Select-String -Path $file.FullName -Pattern $FirstRegex
}
}
这将执行类似于您所要求的操作。这需要 PowerShell 3.0+
$path = 'C:\users\xx\Desktop\mappcent3'
$firstKeyword = "Keyword"
$secondKeyword = "Secondkeyword"
$resultsPath = "C:\Temp\results.csv"
Get-ChildItem $path -Filter "*.txt" | ForEach-Object{
# Read the file in
$fileContents = Get-Content $_.FullName
# Find the first keyword data
$firstKeywordData = ($fileContents | Select-String -Pattern $firstKeyword -Context 0,1 -SimpleMatch).Context.PostContext[0]
# Find the second keyword data
$secondKeywordData = ($fileContents | Select-String -Pattern $secondKeyword -Context 0,1 -SimpleMatch).Context.PostContext[0]
# Create a new object with details gathered.
[pscustomobject][ordered]@{
File = $_.FullName
FirstKeywordData = $firstKeywordData
SecondKeywordData = $secondKeywordData
}
} | Export-CSV $resultsPath -NoTypeInformation
Select-String
是这里最神奇的地方。我们利用 -Context
消耗匹配前后的行。我们想要下面的一个,所以这就是我们使用 0,1
的原因。将其包装在自定义对象中,然后我们可以将其导出到 CSV 文件。
关键字重叠
请注意,您的关键字可能会重叠并在输出文件中产生奇怪的结果。在您的示例中,关键字匹配多行,因此结果集会反映出来。
如果您只是想写回原始文件,您也可以轻松地做到这一点
"$firstKeywordData,$secondKeywordData" | Set-Content $_.FullName
或类似的东西。
Select-String
cmdlet 有一个 -Context
参数,可以轻松提取匹配行之前或之后的行。
您可以使用 Export-Csv
导出您需要的格式(尽管对于 20K 的文件您可能希望直接写入输出文件)
foreach($file in Get-ChildItem C:\users\xx\Desktop\mappcent3 |Where {-not $_.PsIsContainer})
{
$FirstKeyword = 'FirstKeyword'
$FirstLine = Select-String -Path $file.FullName -Pattern $FirstKeyword -Context 0,1 |Select -Expand Context -First 1 |Select -Expand PostContext
$SecondKeyword = 'SecondKeyword'
$SecondLine = Select-String -Path $file.FullName -Pattern $SecondKeyword -Context 0,1 |Select -Expand Context -First 1 |Select -Expand PostContext
New-Object psobject -Property @{$FirstKeyword=$FirstLine;$SecondKeyword=$SecondLine} |Export-Csv (Join-Path $file.DirectoryName ($file.BaseName + '_keywords.txt'))
}