Вопрос или проблема
У меня есть простой текстовый файл:
$ cat food.txt
Яблоки
Бананы
Морковка
Linux/Cygwin
Я могу придумать несколько способов получить номера строк в Linux/Cygwin:
$ nl food.txt
1 Яблоки
2 Бананы
3 Морковка
$ cat -n food.txt
1 Яблоки
2 Бананы
3 Морковка
$ less -NFX food.txt
1 Яблоки
2 Бананы
3 Морковка
PowerShell
Лучший способ, который я придумал, это:
Обновление 2017-11-27: (1) Небольшая корректировка: Out-String -Stream
, чтобы принудительно преобразовать эти надоедливые объекты в текст. (2) Примечание: Я ищу что-то, что будет принимать ВХОДНЫЕ ДАННЫЕ PIPELINE.
PS C:\> function nl{$input | Out-String -Stream | Select-String '.*' | Select-Object LineNumber, Line}
PS C:\> cat .\food.txt | nl
LineNumber Line
---------- ----
1 Яблоки
2 Бананы
3 Морковка
Есть ли более простой способ? Короче? Что-то встроенное в PowerShell?
Я обернул свою строку в функцию, которую вы можете включить в один из ваших профилей Powershell.
Function nl
{
<# .Synopsis
Имитировать инструмент Unic / Linux nl для нумерации строк
.Description
Печать содержимого файла с номерами строк без поддержки оригинальных опций nl
.Example
nl .\food.txt
#>
param (
[parameter(mandatory=$true, Position=0)][String]$FileName
)
process {
If (Test-Path $FileName){
Get-Content $FileName | ForEach{ "{0,5} {1}" -f $_.ReadCount,$_ }
}
}
}
Пример вывода:
> nl .\food.txt
1 Яблоки
2 Бананы
3 Морковка
Это сработает и будет работать с любой командой, которая производит вывод:
$i = 1; cat food.txt | % {$i++;"$($i-1) `t $_"}
Вот вывод:
1 Яблоки
2 Бананы
3 Морковка
Вот пример с выводом каталога:
$i = 1; dir | % {$i++;"$($i-1) `t $_"}
Вот вывод:
1 фоны
2 загрузка
3 inetpub
4 PerfLogs
5 Program Files
6 Program Files (x86)
7 Riot Games
8 Пользователи
9 Windows
10 Reflect_Install.log
Очевидно, если вы хотите, чтобы нумерация строк начиналась с 0, то установите $i = 0
.
Самый короткий метод:
cat log.txt|oss|sls .|select linenumber,line
Предположим, у нас есть food.txt
или создадим его с:
Set-Content food.txt "Яблоки`r`nБананы`r`nМорковка"
Детализированный метод будет следующим:
Get-Content food.txt | Select-String . | Select-Object LineNumber,Line
# LineNumber Line
# ---------- ----
# 1 Яблоки
# 2 Бананы
# 3 Морковка
Сокращённая версия
Вы можете сократить команду, используя их псевдонимы gc
(Get-Content
), sls
(Select-String
) и select
(Select-Object
), что даёт:
gc food.txt | sls . | select linenumber,line
Что происходит?
Get-Content
: извлечет содержимое файлаSelect-String .
:Select-String
является фильтром для ввода строки. В регулярном выражении.
является подстановочным знаком для всего, так что это на самом деле не фильтрует ничего, но мы используемSelect-String
как умный прием, потому что он разбиваетстроку
на объект MatchInfo, который содержит множество полей, таких как:LineNumber
: то, что мы хотим добавить.Line
: содержимое строки.
Select-Object
: мы используем его для фактическоговыбора
полейLineNumber
иLine
.
Если вы уберете Select-Object
, то на самом деле покажется, что ничего не произошло, потому что метод ToString()
от MatchInfo
только печатает часть Line
, так что, явно указав поля с помощью Select-Object
, он преобразуется в PSCustomObject
, чей метод ToString()
будет отображать все поля в удобном читаемом табличном формате.
Использование традиционного for-each
Если вы не хотите использовать хитрые приемы, вы можете придерживаться традиционного метода for-each
, который в powershell
можно сократить до %
$i = 1; gc food.txt | % {"$i `t $_"; $i++}
Это сделает:
- Инициализирует
$i = 1
- Получит содержимое
food.txt
for-each
строкуfood.txt
:- Вернуть
"$i `t $_"
:$i
: номер строки`t
: TAB (табуляция)$_
: содержимое из конвейернойgc food.txt
$i++
: увеличить$i
- Вернуть
.
Ответ или решение
Чтобы получить номера строк в PowerShell, существует несколько способов, каждый из которых можно адаптировать под конкретные нужды. В данной статье мы рассмотрим различные методы, включая как встроенные команды PowerShell, так и кастомные функции.
Основные методы получения номеров строк
1. Использование встроенных команд
Самым простым и удобным способом является использование комбинации команд Get-Content
, Select-String
и Select-Object
. Вот как это можно сделать:
gc food.txt | sls . | select linenumber, line
Объяснение команд:
gc
— это сокращение дляGet-Content
, которое считывает содержимое файла.sls .
— этоSelect-String
, который ищет все строки (так как.
является шаблоном для любой строки), преобразуя каждую строку в объектMatchInfo
, содержащий необходимые поля, такие какLineNumber
иLine
.select linenumber, line
— используется для выбора конкретных полей из объекта.
Такой подход печатает содержимое файла с номерами строк, как показано ниже:
# LineNumber Line
# ---------- ----
# 1 Apples
# 2 Bananas
# 3 Carrots
2. Использование цикла
Если вам больше нравятся традиционные методы итерации, вы можете использовать цикл ForEach
в комбинации с инкрементируемой переменной для номерования строк.
$i = 1; gc food.txt | % {"$i `t $_"; $i++}
Что происходит в этой команде:
$i = 1
— инициализация переменной для номера строки.gc food.txt
— считывание содержимого файла.%
— это сокращение дляForEach-Object
, который перебирает каждую строку в файле."$i
t $_"` — формирует строку с номером и содержимым.$i++
— инкрементирует номер строки после обработки каждой строки.
Вывод будет выглядеть так:
1 Apples
2 Bananas
3 Carrots
3. Кастомные функции
Вы также можете определить свою функцию для получения номеров строк, чтобы сделать код более читаемым и переиспользуемым:
Function nl {
param (
[parameter(mandatory=$true, Position=0)][String]$FileName
)
process {
If (Test-Path $FileName) {
Get-Content $FileName | ForEach-Object { "{0,5} {1}" -f ($_.ReadCount), $_ }
}
}
}
Эта функция принимает имя файла в качестве параметра и выводит содержимое с номерами строк. Примените функцию на примере вашего файла:
nl .\food.txt
Заключение
Эти методы позволяют легко и быстро добавлять номера строк в вывод при работе с текстовыми файлами в PowerShell. Использование встроенных команд и функций делает процесс удобным и адаптируемым под различные сценарии. Выберите подходящий для ваших нужд метод, и вы получите качественный и читаемый вывод, который удобно использовать в дальнейшей работе.
Таким образом, в зависимости от ваших требований, вы можете выбрать любой из предложенных методов для получения номеров строк в PowerShell.