Распечатать строки из файла, который содержит слова, данные пользователем - PullRequest
0 голосов
/ 07 декабря 2018

Я хочу набрать слова, и скрипт напечатает строки, содержащие слова.

У меня есть следующие данные в папке 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 голосов
/ 07 декабря 2018

Ваш 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
0 голосов
/ 07 декабря 2018

Чтобы отфильтровать по списку слов, введенных с помощью 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'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...