Эквивалент 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.
6 ответов
Как и параметры -First и -Last, также есть параметр -Skip, который поможет. Стоит отметить, что -Skip основан на 1, а не на нуле.
# this will skip the first three lines of the text file
cat myfile | select -skip 3
Я не уверен, что в PowerShell есть что-то, что возвращает вам все, кроме последних n предварительно собранных строк. Если вы знаете длину, вы можете просто вычесть 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
Полезная информация распределена по другим ответам здесь, но я думаю, что полезно иметь краткое резюме:
Все строки кроме первых трех
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
Все кроме последнего n
может быть сделано с
... | select -skiplast $n
Если вы используете расширения сообщества PowerShell, существует командлет Take-Object, который будет проходить через все выходные данные, кроме последних N элементов, например:
30# 1..10 | Skip-Object -Last 4
1
2
3
4
5
6
Вы можете сделать это так:
[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
Все кроме первого n
может быть сделано с
... | Select -skip $n
Однако все "но последнее m
"ничего не встроено. Можно выполнить загрузку всего ввода в массив, чтобы получить длину - конечно, для большого ввода, который может привести к необоснованным требованиям к памяти.