none
powershell цветовая подсветка строк . RRS feed

  • Вопрос

  • $path_data | % {
    		$c = $_[3]
    		$t = $_[1]
    		$i = 0
    		$path_data | % {
    			if ( $c -eq $_[3] ) { $i += 1 }
    		}
    		$lim = 0
    		$limits | % {
    			if ( $c -eq $_[2] ) { $lim = $_[3] }
    		}
    		$regular = 'data-category="' + $c + '"'
    		$amount = [regex]::matches($html,$regular).Count / 2
    		
    		$r += (, (, $t, $c, $i, $amount, $lim))
    	}
    
    	$r|% {[pscustomobject]@{Topic = $_[0]; Category = $_[1]; inFolder  = $_[2];inWebsite =$_[3];Limit =$_[4] }}|ft -auto

    Привел участок кода.
    В котором формируются некоторые данные и потом они выводятся на экран в красивой табличке.
    Но очень хочется в этой табличке подсветить цветом некоторые строки удовлетворяющие неким условиям.
    Пытаюсь сделать это так:

    $rr = $r|% {[pscustomobject]@{Topic = $_[0]; Category = $_[1]; inFolder  = $_[2];inWebsite =$_[3];Limit =$_[4] }}|ft -auto
    	$rr | % {
    		if ( $_[2] -eq $_[4] ) { Write-host $_ -ForegroundColor yellow } else { Write-host $_ }
    	}

    Но вместо данных получаю вот такую не понятную штуку.

    4 апреля 2020 г. 13:08

Ответы

  • Пример подсветки строк целиком

    $table = 1..5 | Select-Object @{n = "Title";e = {"Some title $_"}}, @{n='Value1';e={$_}}, @{n='Value2';e={Get-Random $_}} | Format-Table | Out-String $table -split '\r\n' | foreach { $str = $_ if ($_ -match '\s+(?''D1''\d+)\s+(?''D2''\d+)\s*$'){ if( 3 -lt $Matches['D1'] ){Write-Host $str -ForegroundColor Red} else {Write-Host $str -ForegroundColor Green} }

    else{$str} }

    Так это выглядит вживую:

    Пример с тремя колонками значений:

    $table = 1..5 | Select-Object @{n = "Title";e = {"Some title $_"}}, @{n='Value1';e={$_}}, @{n='Value2';e={Get-Random $_}}, @{n='Value3';e={Get-Random 10}}| Format-Table | Out-String 
    $table -split '\r\n' | foreach {
       $str = $_ 
       if ($str -match '\s+(?''D1''\d+)\s+(?''D2''\d+)\s+(?''D3''\d+)\s*$'){
          [int]$D1 = $Matches['D1']
          [int]$D2 = $Matches['D2']
          [int]$D3 = $Matches['D3']
          if ( $D1 -gt $D3 ){ # Если число в первой колонке больше числа из тртей колонки - подсвечиваем строку в красный
             Write-Host $str -ForegroundColor Red
          } else { # В противном случае подсвечиваем в зеленый
             Write-Host $str -ForegroundColor Green
          }
       }else{ # Если строка не расспозналась регулярным выражением - выводим в стандартном цвете
          Write-Host $str
       }
    }


    The opinion expressed by me is not an official position of Microsoft

    • Предложено в качестве ответа Vector BCOModerator 4 апреля 2020 г. 19:02
    • Изменено Vector BCOModerator 5 апреля 2020 г. 15:58 добавил пример с тремя колонками и более сложным условием
    • Помечено в качестве ответа Vector BCOModerator 18 апреля 2020 г. 18:23
    4 апреля 2020 г. 16:43
    Модератор
  • В общем решил не связываться с регулярными выражениями и не парсить недавно созданную таблицу.
    Написал сам форматирование для своих дынных. Получилось на мой взгляд не плохо.
    Но код мой получился какойто не компактый и плохо воспринимаемым.
    Подозреваю что наверняка много где упросить можно?
    Буду рад за любые советы по упрощению кода.

    $topic_max_len = 0 
    	$path_data | % {
    		if ( $_[1].length -gt $topic_max_len ) { $topic_max_len = $_[1].length }
    	}	
    	
    $path_data | % {
    	$c = $_[3]
    	$t = $_[1]
    	$i = 0
    	$path_data | % {
    		if ( $c -eq $_[3] ) { $i += 1 }
    	}
    	$lim = 0
    	$limits | % {
    		if ( $c -eq $_[2] ) { $lim = $_[3] }
    	}
    	$regular = 'data-category="' + $c + '"'
    	$amount = [regex]::matches($html,$regular).Count / 2
    	#Write-Host "Topic - $t - Category $c - in folder $i - in website $amount "
    	$r += (, (, $t, $c, $i, $amount, $lim))
    	
    	$Color="white"
    	if ( $i -eq $lim ) { $Color="yellow" }
    	if ( $i -gt $lim ) { $Color="red" }
    	
    	$output_str = $t
    	$space_len = $topic_max_len - $t.length
    	if ( $space_len -ge 1) { 1..$space_len | % { $output_str +=" " } }
    	$output_str +="    "
    	1..(7 - $c.length) | % { $output_str +=" " }
    	$output_str +=$c
    	1..(4 - $i.ToString().length) | % { $output_str +=" " }
    	$output_str +=$i.ToString()
    	1..(4 - $amount.ToString().length) | % { $output_str +=" " }
    	$output_str +=$amount.ToString()
    	1..(4 - $lim.length) | % { $output_str +=" " }
    	$output_str +=$lim
    	
    	Write-Host $output_str -ForegroundColor $Color
    }

    • Предложено в качестве ответа Vector BCOModerator 18 апреля 2020 г. 18:23
    • Помечено в качестве ответа Vector BCOModerator 18 апреля 2020 г. 18:23
    5 апреля 2020 г. 4:23

Все ответы

  • приведите пример таблички и данных чтоб можно было восспроизвести непонятную штуку и ее поправить

    The opinion expressed by me is not an official position of Microsoft

    4 апреля 2020 г. 13:50
    Модератор
  • Здравствуйте,

    Уточните пожалуйста, а пробовали использовать Out-String перед выводом данных?
    Как на пример указано в дискусии на стороннем форуме - How to display formatted output with Write-Host.

    Avis de non-responsabilité:
    Mon opinion ne peut pas coïncider avec la position officielle de Microsoft.

    Bien cordialement, Andrei ...

    MCP

    • Изменено SQxModerator 4 апреля 2020 г. 14:43 обновлено
    • Предложено в качестве ответа Vector BCOModerator 4 апреля 2020 г. 19:02
    4 апреля 2020 г. 14:43
    Модератор
  • вы хотите подсветить всю строку, или только ее фрагмент?

    The opinion expressed by me is not an official position of Microsoft

    4 апреля 2020 г. 14:49
    Модератор
  • Дело в том, что команда Format-Table, которую вы применили, возвращает отнюдь не строки, а набор объектов с примененным форматированием в некоем внутреннем формате, с которым PS, по-видимому, знает как обращаться, если получает их напрямую из команды, но не как массив, в который записан результат из конвейера. А то, что PS получает в виде массива - он тупо преобразует в строки вызовом метода ToString - который для объектов большинства классов возвращает полное имя класса (это реализация по умолчанию из System.Object). Это - то, что вы видите.

    В принципе, в PS есть средства для настройки поведения команд форматирования Format-XXX - Formatting File, но, насколько мне известно, поддержки цветов там нет. Так что придется вам писать форматирование вывода самому, без использования команды Format-Table. Иначе - никак.

    PS Чисто теоретически: поскольку исходники PS открыты и вообще тип проекта - jpen-source, то вы можете добавить поддержку цветов в существующие команды, и даже послать запрос на добавление этой поддержки в PS.


    Слава России!

    4 апреля 2020 г. 14:52
  • Пример подсветки строк целиком

    $table = 1..5 | Select-Object @{n = "Title";e = {"Some title $_"}}, @{n='Value1';e={$_}}, @{n='Value2';e={Get-Random $_}} | Format-Table | Out-String $table -split '\r\n' | foreach { $str = $_ if ($_ -match '\s+(?''D1''\d+)\s+(?''D2''\d+)\s*$'){ if( 3 -lt $Matches['D1'] ){Write-Host $str -ForegroundColor Red} else {Write-Host $str -ForegroundColor Green} }

    else{$str} }

    Так это выглядит вживую:

    Пример с тремя колонками значений:

    $table = 1..5 | Select-Object @{n = "Title";e = {"Some title $_"}}, @{n='Value1';e={$_}}, @{n='Value2';e={Get-Random $_}}, @{n='Value3';e={Get-Random 10}}| Format-Table | Out-String 
    $table -split '\r\n' | foreach {
       $str = $_ 
       if ($str -match '\s+(?''D1''\d+)\s+(?''D2''\d+)\s+(?''D3''\d+)\s*$'){
          [int]$D1 = $Matches['D1']
          [int]$D2 = $Matches['D2']
          [int]$D3 = $Matches['D3']
          if ( $D1 -gt $D3 ){ # Если число в первой колонке больше числа из тртей колонки - подсвечиваем строку в красный
             Write-Host $str -ForegroundColor Red
          } else { # В противном случае подсвечиваем в зеленый
             Write-Host $str -ForegroundColor Green
          }
       }else{ # Если строка не расспозналась регулярным выражением - выводим в стандартном цвете
          Write-Host $str
       }
    }


    The opinion expressed by me is not an official position of Microsoft

    • Предложено в качестве ответа Vector BCOModerator 4 апреля 2020 г. 19:02
    • Изменено Vector BCOModerator 5 апреля 2020 г. 15:58 добавил пример с тремя колонками и более сложным условием
    • Помечено в качестве ответа Vector BCOModerator 18 апреля 2020 г. 18:23
    4 апреля 2020 г. 16:43
    Модератор
  • В общем решил не связываться с регулярными выражениями и не парсить недавно созданную таблицу.
    Написал сам форматирование для своих дынных. Получилось на мой взгляд не плохо.
    Но код мой получился какойто не компактый и плохо воспринимаемым.
    Подозреваю что наверняка много где упросить можно?
    Буду рад за любые советы по упрощению кода.

    $topic_max_len = 0 
    	$path_data | % {
    		if ( $_[1].length -gt $topic_max_len ) { $topic_max_len = $_[1].length }
    	}	
    	
    $path_data | % {
    	$c = $_[3]
    	$t = $_[1]
    	$i = 0
    	$path_data | % {
    		if ( $c -eq $_[3] ) { $i += 1 }
    	}
    	$lim = 0
    	$limits | % {
    		if ( $c -eq $_[2] ) { $lim = $_[3] }
    	}
    	$regular = 'data-category="' + $c + '"'
    	$amount = [regex]::matches($html,$regular).Count / 2
    	#Write-Host "Topic - $t - Category $c - in folder $i - in website $amount "
    	$r += (, (, $t, $c, $i, $amount, $lim))
    	
    	$Color="white"
    	if ( $i -eq $lim ) { $Color="yellow" }
    	if ( $i -gt $lim ) { $Color="red" }
    	
    	$output_str = $t
    	$space_len = $topic_max_len - $t.length
    	if ( $space_len -ge 1) { 1..$space_len | % { $output_str +=" " } }
    	$output_str +="    "
    	1..(7 - $c.length) | % { $output_str +=" " }
    	$output_str +=$c
    	1..(4 - $i.ToString().length) | % { $output_str +=" " }
    	$output_str +=$i.ToString()
    	1..(4 - $amount.ToString().length) | % { $output_str +=" " }
    	$output_str +=$amount.ToString()
    	1..(4 - $lim.length) | % { $output_str +=" " }
    	$output_str +=$lim
    	
    	Write-Host $output_str -ForegroundColor $Color
    }

    • Предложено в качестве ответа Vector BCOModerator 18 апреля 2020 г. 18:23
    • Помечено в качестве ответа Vector BCOModerator 18 апреля 2020 г. 18:23
    5 апреля 2020 г. 4:23
  • не знаю как вам, а я теряюсь во многочисленных $_[1], $_[2], $_[3], $c, $t, $i и тд.

    как по мне оперировать обьектами с именоваными свойствами намного приятней и проще

    например вы можете создать массив обьектов с полями Topic, TopicLenth, Category, CategoryLength, InFolder, OnWebSite, Limit после чего оперировать массивом этих обьектов

    $FirstColumnLenhgt = $ObjectsArraj | Sort TopicLenght | Select -Last 1 -ExpandPropertie TopicLength 

    итд.

    тоже самое можно делать и с $_[2], $c, $z и прочими но при этом код становится нечитаемым

    пс рабочую регулярку я выше написал


    The opinion expressed by me is not an official position of Microsoft

    5 апреля 2020 г. 7:42
    Модератор