Как делать то, что 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
Wisbucky
источник
но комментарий Джои, кажется, указывает на прямо противоположное! как мне узнать, кому доверять и какой (встроенный) метод наиболее эффективен?
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.

Патрик Беруэлл
источник