Как делать то, что head, tail, more, less, sed делают в Powershell? [закрыто]


110

На окнах, с помощью Powershell, каковы эквивалентные команды для Линукса head, tail, more, lessи sed?


файл журнала слишком велик, около нескольких мегабайт. Notepad.exe слишком сложно просматривать.
— Юэ Чжан

Если вы используете в notepadкачестве основы, я бы посоветовал взглянуть на альтернативные текстовые редакторы, есть множество (как бесплатных, так и платных) альтернатив. Все они лучше блокнота (хотя это не такая уж проблема).
— Ричард

возможный дубликат PowerShell и Unix Shells
— manojlds

Я имею дело с большими файлами и использую / устанавливаю Vim, который работает намного быстрее, чем любой другой инструмент, который я использовал.
— sfanjoy

Ответы:


176

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

Это работает достаточно хорошо для небольших файлов, большие (более нескольких МБ), вероятно, немного медленны.

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


3
Святая корова, мой процессор полностью исчерпал возможности для работы -last 2с CSV объемом 1 ГБ. Горячий напиток: ☕
— mlissner

9
@mlissner: если вы используете PowerShell v3, вы можете использовать Get-Content -Tail 2вместо него. Это определенно быстрее.
— Joey

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

53

Вот встроенные способы сделать 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 Мой ответ согласуется с комментарием Джои. В его комментарии говорится: «-Last медленно ... Вот почему существует Get-Content -Tail». | select -lastиспользует трубы. Пользуюсь -tailбез трубы. Но если вы когда-нибудь найдете два противоречивых ответа, вы, вероятно, сможете доверять человеку с гораздо более высокой репутацией. Кроме того, вы можете просто попробовать два метода для большого файла. Это будет очень заметно на большом файле.
— wisbucky

Понял. Извините, я, должно быть, запутался, когда впервые прочитал сообщения.
— NH.

8

more.exeсуществует в Windows, порты lessлегко найти (и PowerShell Community Extensions , 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, добро пожаловать в Stack Overflow! Спасибо за попытку ответить на этот вопрос, не могли бы вы дать более подробное объяснение? Непонятно, пытаетесь ли вы предложить решение или просто добавить комментарий о проблеме.
— Росио Гарсиа Луке

Это был комментарий и разочарование. '-TotalCount "ничего не делает" -Head еще не выполняет. Так кто-нибудь знает, как получить TotalCount?
— Патрик Беруэлл

Прочтите еще раз ... Я добавил К ответу и пояснил, что работает ...
— Патрик Беруэлл

1

Если вам нужно запросить большие (или маленькие) файлы журналов в Windows, лучший инструмент, который я нашел, - это бесплатный Log Parser 2.2 от Microsoft . Вы можете вызвать его из PowerShell, если хотите, и он сделает всю тяжелую работу за вас, причем очень быстро.


в любом случае спасибо, Моя среда - Win2k8R2, которой нет в Системных требованиях Log Parser2.2
— Юэ Чжан,

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. Кстати, ваш код работает только с опцией «sed». Все остальное игнорирует все, кроме gc и path.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.