从文件中打印出包含用户给出的单词的行

时间:2018-12-07 13:44:24

标签: powershell

我想输入单词,脚本将打印包含单词的行。

我在foods.txt文件夹中有以下数据

1;400;100000;pizza tea
11;178;56124;coke hamburger
7;777;20000;sprite pizza
10;150;100000;coke sandwich fries

例如,如果我输入披萨,它将打印出第一行和第三行:

1;400;100000;pizza tea
7;777;20000;sprite pizza

我的脚本可以过滤一个单词,但是我不知道如何使它过滤所有给定的单词,因此如果我输入:tea fries,它应该打印出第一行和最后一行。

我正在考虑过滤主文件,然后将其重定向到另一个文件,也过滤该文件,或者类似的东西?

$word = Read-Host "Type in the words"
Copy-Item foods.txt first.txt

foreach ($i in Get-ChildItem *first.txt) {
    $filtered = Get-Content "foods.txt" | % {
        if ($_ -match "$word") {
            Write-Host $_
        }
    }
    $filtered >> second.txt
    Copy-Item second.txt first.txt
}
Get-Content second.txt
Remove-Item first.txt
Remove-Item first.txt

2 个答案:

答案 0 :(得分:1)

要过滤通过Read-Host输入的单词列表,您需要分割输入并从标记中构建正则表达式:

$words = Read-Host '...'
$re = ($words.Split() | Where-Object {$_} | ForEach-Object {[regex]::Escape($_)}) -join '|'

如果您的单词不包含在正则表达式中具有特殊含义的字符(例如点或方括号),或者无论如何都希望将它们作为正则表达式处理,则可以省略步骤| ForEach-Object {[regex]::Escape($_)}

此外,PowerShell比较运算符还用作枚举器,因此您可以在数组上直接使用它们:

(Get-Content 'foods.txt') -match $re | Set-Content 'result.txt'

答案 1 :(得分:1)

您的foods.txt文件看起来非常像CSV文件,但没有标题。 这意味着您也可以使用CSV解析方法进行此操作:

# Import the file as CSV to get an array of objects.
# I'm just making up the headers here..
$foods = Import-Csv -Path 'foods.txt' -Delimiter ';' -Header 'ItemsSoldToday','ItemsSoldThisWeek','InStock','Description'

# Next, read the words typed in by the user, split on whitespace character(s) 
# and escape any characters that might have special meaning in a regular expression
$words = (Read-Host "Type in the words separated by a space character") -split '\s+' | ForEach-Object { [regex]::Escape($_) }
# Join these words together with a pipe symbol "|" that will make an 'OR' within the regex match
# and filter the objects that have any of these words in the 'Description' field
$chosen = $foods | Where-Object { $_.Description -match ($words -join '|') }

# Example: when the user types "tea fries", $chosen now contains an array of objects:
#
#   ItemsSoldToday ItemsSoldThisWeek InStock Description        
#   -------------- ----------------- ------- -----------        
#   1              400               100000  pizza tea          
#   10             150               100000  coke sandwich fries


# If you want the returned output to be exactly like the input text file, simply recombine the values
$chosen | ForEach-Object { $_.PSObject.Properties.Value -join ';' }

这将返回:

1;400;100000;pizza tea
10;150;100000;coke sandwich fries