Як робити те, що роблять голова, хвіст, більше, менше, сед у Powershell? [зачинено]


109

На вікнах, з допомогою Powershell, які еквівалентні команди для Лінукса head, tail, more, lessі sed?


Файл журналу занадто великий, приблизно кілька Мбайт. Це занадто важко для перегляду через notepad.exe.
Юе Чжан

Якщо ви використовуєте notepadяк свою базу, я б запропонував переглянути альтернативні текстові редактори, є безліч (і безкоштовних, і платних) альтернатив. Усі перевершують блокнот (хоч це і не є великим завданням).
Річард

можливий дублікат PowerShell vs. Unix Shells
manojlds

Я маю справу з великими файлами і використовую / встановлюю Vim, що виявляється набагато швидше, ніж будь-який інший інструмент, який я використовував.
sfanjoy

Відповіді:


174

Get-Content(псевдонім:) gc- ваш звичайний варіант для читання текстового файлу. Потім можна додатково фільтрувати:

gc log.txt | select -first 10 # head
gc -TotalCount 10 log.txt     # also head
gc log.txt | select -last 10  # tail
gc -Tail 10 log.txt           # also tail (since PSv3), also much faster than above option
gc log.txt | more             # or less if you have it installed
gc log.txt | %{ $_ -replace '\d+', '($0)' }         # sed

Це працює досить добре для невеликих файлів, більші файли (більше декількох MiB), ймовірно, трохи повільні.

У PowerShell Community Extensions включають деякі командлети для спеціалізованого файлу матеріалу (наприклад , Get-FileTail).


3
Свята корова, це збільшить мій процесор, щоб зробити -last 2на CSV 1 Гб. Гарячий напій: ☕
mlissner

9
@mlissner: Якщо ви перебуваєте на PowerShell v3, ви можете використовувати її Get-Content -Tail 2замість. Це, безумовно, швидше.
Джої

gc log.txt | %{ $_ -replace '\d+', '($0)' } # sedце насправді не повністю інструмент sed, оскільки він не повертає вміст назад. Він потребує Set-Content.
Артем

3
@Neil, -Lastповільно з тієї ж причини awkбуло б повільним для тієї ж задачі: він повинен спочатку споживати потік. Ось чому Get-Content -Tailіснує. І немає, headтому що він не вписується в конвенції про іменування, а його призначення вже виконується Select-Item.
Joey

3
@neil @joey Вони мають псевдонім для -head. Дивіться мою відповідь stackoverflow.com/a/41626586/1081043
wisbucky

52

Ось вбудовані способи зробити headі tail. Не використовуйте труби, тому що якщо у вас великий файл, він буде дуже повільним. Використання цих вбудованих параметрів буде надзвичайно швидким навіть для величезних файлів.

gc log.txt -head 10 
gc log.txt -tail 10
gc log.txt -tail 10 -wait # equivalent to tail -f

але коментар Джої, схоже, вказує на навпаки! як я можу знати, кому довіряти чи який (вбудований) метод є найбільш ефективним?
NH.

2
@NH Моя відповідь узгоджується з коментарем Джої. У його коментарі написано: "Останній повільно ... Ось чому Get-Content -Tail існує". | select -lastвикористовує труби. Я використовую -tailбез труб. Але якщо ви коли-небудь знайдете дві суперечливі відповіді, ви, ймовірно, можете довірити людину зі значно вищою репутацією. Крім того, ви можете просто спробувати два способи у великому файлі. Це буде дуже очевидно у великому файлі.
Вісбукі

Зрозумів. Вибачте, я, мабуть, заплутався, коли читав пости.
NH.

8

more.exeіснує в Windows, порти lessлегко знаходяться (а розширення спільноти PowerShell , PSCX, включає в себе один).

PowerShell насправді не пропонує жодної альтернативи окремим програмам, але для структурованих даних Out-Gridможе бути корисно.

Headі Tailможуть бути імітовані за Select-Objectдопомогою відповідно -Firstі -Lastпараметрів.

Sedфункції доступні, але структуровані досить по-різному. Параметри фільтрації доступні у Where-Object(або через Foreach-Objectта деякий стан для діапазонів). Інші, трансформуючі, операції можна виконувати за допомогою Select-Objectта Foreach-Object.

Однак, як PowerShell передає (.NET) об'єкти - з усією їх набраною структурою, наприклад. Дати залишаються DateTimeекземплярами - а не просто рядками, які кожна команда потребує розбору, значна частина sedінших програм є зайвою.


Блискуча. Здається, gc не підтримує вхід труб. коли я хочу відфільтрувати вихід команди, я використовую "... exe ... | select-object-first 20 | select-object -last 1"
A117

2

"-TotalCount" у цьому випадку відповідає точно так само, як "-head". Ви повинні використовувати -TotalCount або -head для виконання такої команди. Але -TotalCount вводить в оману - він не працює АКТУАЛЬНО, даючи вам будь-які підрахунки ...

gc -TotalCount 25 C:\scripts\logs\robocopy_report.txt

Вищеописаний сценарій, протестований на PS 5.1, є однаковою відповіддю, як показано нижче ...

gc -head 25 C:\scripts\logs\robocopy_report.txt

Тож просто просто використовуйте "-head 25" вже!


Привіт @Patrick! Ласкаво просимо в стек переповнення! Дякуємо, що спробували відповісти на це запитання, чи можете ви надати більш детальне пояснення? Незрозуміло, ви намагаєтесь запропонувати рішення чи просто додати коментар щодо проблеми.
Rocío García Luque

Це був коментар, а також розчарування. "-TotalCount" нічого не робить "Голова" ще не робить. Тож хтось знає, як отримати TotalCount?
Патрік

Прочитайте ще раз ... я додав відповідь і уточнив, що працює ...
Патрік Бервелл

1

Якщо вам потрібно здійснити запит великих (або малих) файлів журналів у Windows, найкращим інструментом, який я знайшов, є безкоштовний Microsoft Log Parser 2.2 . Ви можете зателефонувати йому в PowerShell, якщо хочете, і він зробить все важке підняття для вас, і дуже швидко теж.


все одно дякую, моє оточення - це Win2k8R2, якого немає в Системних вимогах Log Parser2.2
Yue Zhang

0

Я отримав кілька кращих рішень:

gc log.txt -ReadCount 5 | %{$_;throw "pipeline end!"} # head
gc log.txt | %{$num=0;}{$num++;"$num $_"}             # cat -n
gc log.txt | %{$num=0;}{$num++; if($num -gt 2 -and $num -lt 7){"$num $_"}} # sed

-1
$Push_Pop = $ErrorActionPreference #Suppresses errors
$ErrorActionPreference = SilentlyContinue #Suppresses errors
#Script
    #gc .\output\*.csv -ReadCount 5 | %{$_;throw "pipeline end!"} # head
    #gc .\output\*.csv | %{$num=0;}{$num++;"$num $_"}             # cat -n
    gc .\output\*.csv | %{$num=0;}{$num++; if($num -gt 2 -and $num -lt 7){"$num $_"}} # sed
#End Script 
$ErrorActionPreference = $Push_Pop #Suppresses errors

Ви не отримуєте всіх помилок з кодом pushpop BTW, ваш код працює лише з опцією "sed". Всі інші ігнорують що-небудь, крім gc та шляху.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.