Счетчик приращений внутри цикла Foreach-Object - PullRequest
0 голосов
/ 26 ноября 2018

Я хочу вывести каждую строку в текстовом документе в свой собственный документ, где выходные документы имеют имена 1.txt, 2.txt и т. Д. Это мой исходный код, который читает текстовые документы и выводит строки одну за другой..

get-content "artists.txt" | Foreach-Object {$_ | set-content "artists\$counter.txt"}

Но, как вы можете себе представить, это всегда приводит к одному и тому же документу.

Я пробовал

get-content "artists.txt" | 
  Foreach-Object {$_ | set-content "artists\$counter.txt" } {$counter++}

, как я видел в Интернете и покаэто увеличивает счетчик, он не делает то, что я хочу (так как он все еще выводит в тот же файл).

Не совсем уверен, куда вставить здесь счетчик ++, так как внутри самого цикла Foreach-Object выдает ошибку (если я не вставляю его неправильно).

Спасибо.

Ответы [ 3 ]

0 голосов
/ 27 ноября 2018

Полезный ответ Мартина Брандла предоставляет эффективное решение, основанное на свойстве - ReadCount с неясным именем, которое Get-Content добавляет к каждой строке ввода, что отражает -основную строку *1006*число .

Использование блока сценариев с привязкой к задержке позволяет получить решение, которое является одновременно более коротким и заметно более быстрым:

Get-Content artists.txt | Set-Content -LiteralPath { "artists\$($_.ReadCount).txt" }

Что касается что вы пытались :

Переменная $counter должна быть увеличена в блоке ForEach-Object команды -Process, т. Е. В блоке, который выполняется для каждого входного объекта (и обычно это только указанный блок, позиционно ).

2-й блок сценария, который вы передали, {$counter++}, привязывается к параметру -End, что означает блок, который должен быть выполнен один раз , после все объекты конвейера были получены.

Следовательно, вы могли бы использовать следующее:

$counter = 0
Get-Content artists.txt | Foreach-Object { 
  $_ | Set-Content "artists\$((++$counter)).txt"
}

Операция приращения встроенав расширяемой строке для краткости, но вы могли бы сделать это отдельнымte оператор.

Обратите внимание на использование дополнительной пары (...) вокруг выражения ++$counter, чтобы гарантировать, что значение выражения также output ;по умолчанию ++ просто увеличивает значение переменной, но не производит вывод.
Внешний $(...) - оператор подвыражения - необходим для встраивания выражений или команд в расширяемые строки ("...").

0 голосов
/ 27 ноября 2018

В однострочниках объект For-Each имеет три позиционных блока: begin, process и end:

...<piped objects>... | For-Each {...begin...} {...process...} {...end...}

Простой и общий способ настройки счетчика::

...<piped objects>... | For-Each {$counter = 0} {...process...} {...end...}

, потому что если вам нужно повторно использовать однострочник, переменная $counter не будет сброшена.Вы также можете добавить код в блок begin, чтобы запустить счетчик в другом месте.

Для вашего конкретного случая нам просто нужно инициализировать $counter в блоке begin и использовать * 1016Ответ * mklement0 :

get-content "artists.txt" | Foreach-Object {$counter = 0} {$_ | set-content "artists\$((++$counter.txt))"}

Вы даже можете использовать блок end для вывода сводки:

For-Each {...} {...} {Write-Host "There were $counter lines read and $counter files created"}
0 голосов
/ 26 ноября 2018

В вашем случае вы можете использовать свойство ReadCount, возвращаемое командлетом Get-Content:

get-content "artists.txt" | Foreach-Object {$_ | set-content "artists\$($_.ReadCount).txt" }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...