Як робити те, що роблять голова, хвіст, більше, менше, сед у 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.