Эквивалент PowerShell для "head -n-3"?
Я был в состоянии отследить основные функциональные возможности головы/хвоста:
head -10 myfile <==> cat myfile | select -first 10
tail -10 myfile <==> cat myfile | select -last 10
Но если я хочу перечислить все строки, кроме последних трех или всех строк, кроме первых трех, как вы это сделаете? В Unix я мог сделать "head -n-3" или "tail -n + 4". Не очевидно, как это должно быть сделано для PowerShell.
Ответы
Ответ 1
Как и параметры -First и -Last, есть также параметр -Skip, который поможет. Стоит отметить, что -Skip 1, а не ноль.
# this will skip the first three lines of the text file
cat myfile | select -skip 3
Я не уверен, что у PowerShell есть что-то, что возвращает вам все, кроме предварительно построенных последних строк. Если вы знаете длину, вы можете просто вычесть n из числа строк и использовать параметр -First из select. Вы также можете использовать буфер, который пропускает только строки, когда он заполняется.
function Skip-Last {
param (
[Parameter(Mandatory=$true,ValueFromPipeline=$true)][PsObject]$InputObject,
[Parameter(Mandatory=$true)][int]$Count
)
begin {
$buf = New-Object 'System.Collections.Generic.Queue[string]'
}
process {
if ($buf.Count -eq $Count) { $buf.Dequeue() }
$buf.Enqueue($InputObject)
}
}
В качестве демонстрации:
# this would display the entire file except the last five lines
cat myfile | Skip-Last -count 5
Ответ 2
Полезная информация распространяется на другие ответы здесь, но я думаю, что полезно иметь краткий обзор:
Все строки, кроме первых трех
1..10 | Select-Object -skip 3
returns (one per line): 4 5 6 7 8 9 10
Все строки, кроме последних трех
1..10 | Select-Object -skip 3 -last 10
returns (one per line): 1 2 3 4 5 6 7
То есть, вы можете сделать это со встроенными командами PowerShell, но есть такая досада, когда нужно указывать размер входящего. Простым обходным решением является просто использовать константу, большую, чем любой возможный ввод, и вам не нужно будет знайте размер априори:
1..10 | Select-Object -skip 3 -last 10000000
returns (one per line): 1 2 3 4 5 6 7
Чистый синтаксис заключается в том, чтобы использовать, как предложил Кейт Хилл, командлет Skip-Object из расширений сообщества PowerShell (функция Skip-Last в ответе Goyuix выполняется аналогично, но использование PSCX избавляет вас от необходимости поддерживать код):
1..10 | Skip-Object -last 3
returns (one per line): 1 2 3 4 5 6 7
Первые три строки
1..10 | Select-Object –first 3
returns (one per line): 1 2 3
Последние три строки
1..10 | Select-Object –last 3
returns (one per line): 8 9 10
Средние четыре строки
(Это работает, потому что -skip
обрабатывается до -first
, независимо от порядка параметров в вызове.)
1..10 | Select-Object -skip 3 -first 4
returns (one per line): 4 5 6 7
Ответ 3
Если вы используете Расширения сообщества PowerShell, есть командлет Take-Object, который пройдет через весь вывод, кроме последних N элементов например:
30# 1..10 | Skip-Object -Last 4
1
2
3
4
5
6
Ответ 4
Вы можете сделать это следующим образом:
[array]$Service = Get-Service
$Service[0] #First Item
$Service[0..2] #First 3 Items
$Service[3..($Service.Count)] #Skip the first 3 lines
$Service[-1] #Last Item
$Service[-3..-1] #Last 3 Items
$Service[0..($Service.Count -4)] #Skip the last 3 lines
Ответ 5
Все, кроме первого n
, можно выполнить с помощью
... | Select -skip $n
Однако все "но последние m
" не имеют ничего встроенного. Это выполнимо, загружая весь вход в массив, чтобы получить длину - конечно, для большого ввода, который может поставить необоснованные требования к памяти.
Ответ 6
Все, кроме последнего n
, можно выполнить с помощью
... | select -skiplast $n