itsource

PowerShell 언어에서 가장 유용하지만 거의 알려지지 않은 기능은 무엇입니까?

mycopycode 2023. 10. 4. 21:52
반응형

PowerShell 언어에서 가장 유용하지만 거의 알려지지 않은 기능은 무엇입니까?

얼마 전에 저는 PowerShell의 다양한 과제에 대해 읽고 있었습니다.이를 통해 이와 같은 작업을 수행할 수 있습니다.

64 >  $a,$b,$c,$d = "A four word string".split()

65 >  $a
A

66 >  $b
four

또는 단일 문에서 변수를 교환할 수 있습니다.

$a,$b = $b,$a

잘 알려지지 않은 PowerShell 덩어리 중에는 어떤 것들이 있습니까?

$$지휘. 반복 해야 하는 .동일한 파일 경로에 대해 반복 작업을 수행해야 하는 경우가 많습니다.예를 들어 파일을 확인한 다음 VIM에서 파일을 엽니다.$$은 이 사소한를 만듭니다.

PS> tf edit some\really\long\file\path.cpp
PS> gvim $$

짧고 간단하지만 시간을 많이 절약할 수 있습니다.

PowerShell의 가장 강력한 기능은 ScriptBlock 지원입니다.어떤 유형의 제약 없이 효과적으로 익명의 방법을 간결하게 전달할 수 있다는 사실은 C++ 함수 포인터처럼 강력하고 C# 또는 F# 람다처럼 쉽습니다.

ScriptBlocks를 사용하면 (PowerShell에는 원래 존재하지 않는) "사용" 문을 구현할 수 있다는 것이 얼마나 멋진 일인지를 의미합니다.또는 v2 이전에는 Try-catch-finally를 구현할 수도 있습니다.

function Using([Object]$Resource,[ScriptBlock]$Script) {
    try {
        &$Script
    }
    finally {
        if ($Resource -is [IDisposable]) { $Resource.Dispose() }
    }
}

Using ($File = [IO.File]::CreateText("$PWD\blah.txt")) {
   $File.WriteLine(...)
}

얼마나 멋진데요!

제가 종종 간과하는 기능은 파일을 스위치 문에 전달하는 기능입니다.

스위치는 줄을 반복하여 문자열(또는 -regex 매개 변수가 있는 정규식)과 일치합니다. 변수, 숫자 또는 줄의 내용을 전달하여 $true 또는 $false로 평가할 수 있습니다.

switch -file 'C:\test.txt' 
{   
  'sometext' {Do-Something}   
  $pwd {Do-SomethingElse}  
  42 {Write-Host "That's the answer."}  
  {Test-Path $_} {Do-AThirdThing}  
  default {'Nothing else matched'} 
}

$OFS - 출력 필드 구분 기호.문자열로 렌더링할 때 배열 요소가 분리되는 방법을 지정하는 편리한 방법:

PS> $OFS = ', '
PS> "$(1..5)"
1, 2, 3, 4, 5
PS> $OFS = ';'
PS> "$(1..5)"
1;2;3;4;5
PS> $OFS = $null # set back to default
PS> "$(1..5)"
1 2 3 4 5

항상 배열 결과를 보장합니다.다음 코드를 고려합니다.

PS> $files = dir *.iMayNotExist
PS> $files.length

이 경우 $file은 $null, 스칼라 값 또는 값의 배열일 수 있습니다.$files.length는 $null 또는 단일 파일의 파일 수를 알려주지 않습니다.단일 파일 케이스에서는 파일 크기가 나옵니다!!데이터 양을 다시 가져올지 확신할 수 없을 때마다 명령어는 항상 다음과 같이 배열 하위 표현식에 포함됩니다.

PS> $files = @(dir *.iMayNotExist)
PS> $files.length # always returns number of files in array

그러면 $files는 항상 배열이 됩니다.비어 있거나 단일 요소만 포함되어 있을 수 있지만 배열이 됩니다.이를 통해 결과에 대한 추론이 훨씬 간단해집니다.

배열 공분산 지원:

PS> $arr = '127.0.0.1','192.168.1.100','192.168.1.101'
PS> $ips = [system.net.ipaddress[]]$arr
PS> $ips | ft IPAddressToString, AddressFamily -auto

IPAddressToString AddressFamily
----------------- -------------
127.0.0.1          InterNetwork
192.168.1.100      InterNetwork
192.168.1.101      InterNetwork

Compare-Object를 사용하여 배열 비교:

PS> $preamble = [System.Text.Encoding]::UTF8.GetPreamble()
PS> $preamble | foreach {"0x{0:X2}" -f $_}
0xEF
0xBB
0xBF
PS> $fileHeader = Get-Content Utf8File.txt -Enc byte -Total 3
PS> $fileheader | foreach {"0x{0:X2}" -f $_}
0xEF
0xBB
0xBF
PS> @(Compare-Object $preamble $fileHeader -sync 0).Length -eq 0
True

이와 같은 더 많은 것에 대해서는, 무료 eBook - Effective PowerShell을 확인해 보세요.

다변수 할당의 선을 따라.

$list = 1,2,3,4

While($list) {
$head, $list= $list
$head
}

1
2
3
4

난 이걸 사용해왔습니다.

if (!$?) {  # if previous command was not successful
    Do some stuff
}

또한 $_(현재 파이프라인 객체)를 꽤 많이 사용하지만, 다른 것들보다 더 많이 알려져 있을 수도 있습니다.

많은 연산자가 어레이에서도 작업을 수행하여 비교가 참인 요소를 반환하거나 어레이의 각 요소에 대해 독립적으로 작업한다는 사실:

1..1000 -lt 800 -gt 400 -like "?[5-9]0" -replace 0 -as "int[]" -as "char[]" -notmatch "\d"

은 .Where-Object.

언어 기능은 아니지만 매우 도움이 됩니다.

f8 해당 --합니다.

#로 사용자의 기록을 검색합니다.

예:

PS> Get-Process process
PS> "포드 익스플로러"
PS> "마젤란" | 추가- 내용 "위대한 탐험가.txt"
PS> 유형 "great explaners.txt"
PS> #expl <-- expl> 키를 눌러 "expl"이라는 용어가 있는 히스토리 항목을 순환합니다.

이 실이 너무 좋아요.윈도우 파워셸 인 액션을 읽고 많은 것들을 나열할 수 있었습니다.그 책과 설명서 사이에 단절이 있습니다.저는 사실 여기 다른 곳에 다 나열하려고 했지만 "문제가 되지 않는다"는 이유로 보류되었습니다.

각각의 스크립트 블록 3개(시작/프로세스/종료)로 시작하겠습니다.

Get-ChildItem | ForEach-Object {$sum=0} {$sum++} {$sum}

두 개의 변수를 교환하는 것에 대해 말하자면, 다음은 두 개의 파일을 교환하는 것입니다.

${c:file1.txt},${c:file2.txt} = ${c:file2.txt},${c:file1.txt}

파일 검색 및 바꾸기:

${c:file.txt} = ${c:file.txt} -replace 'oldstring','newstring'

어셈블리 및 네임스페이스 문 사용:

using assembly System.Windows.Forms
using namespace System.Windows.Forms
[messagebox]::show('hello world')

속성 및 메서드가 포함된 foreach의 짧은 버전

ps | foreach name
'hi.there' | Foreach Split .

문자열 외부에 $() 연산자를 사용하여 두 문장을 결합합니다.

$( echo hi; echo there ) | measure

변수가 있는 Get-content/Set-content:

$a = ''
get-content variable:a | set-content -value there

익명 함수:

1..5 | & {process{$_ * 2}}

익명 함수에 이름을 지정합니다.

$function:timestwo = {process{$_ * 2}}

매개 변수가 있는 익명 함수:

& {param($x,$y) $x+$y} 2 5

일반적으로 다음을 수행할 수 없는 경우 이를 사용하여 foreach()에서 스트리밍할 수 있습니다.

& { foreach ($i in 1..10) {$i; sleep 1} } | out-gridview

유닉스 '&'처럼 백그라운드에서 프로세스를 실행한 후 대기합니다.

$a = start-process -NoNewWindow powershell {timeout 10; 'done a'} -PassThru
$b = start-process -NoNewWindow powershell {timeout 10; 'done b'} -PassThru
$c = start-process -NoNewWindow powershell {timeout 10; 'done c'} -PassThru
$a,$b,$c | wait-process

또는 워크플로우의 각 병렬에 대해:

workflow work {
  foreach -parallel ($i in 1..3) { 
    sleep 5 
    "$i done" 
  }
}

work

또는 다양한 작업을 실행할 수 있는 워크플로 병렬 블록:

function sleepfor($time) { sleep $time; "sleepfor $time done"}

workflow work {
  parallel {
    sleepfor 3
    sleepfor 2
    sleepfor 1
  }
  'hi'
}

work 

api로 3개의 실행 공간에서 3개의 병렬 명령:

$a =  [PowerShell]::Create().AddScript{sleep 5;'a done'}
$b =  [PowerShell]::Create().AddScript{sleep 5;'b done'}
$c =  [PowerShell]::Create().AddScript{sleep 5;'c done'}
$r1,$r2,$r3 = ($a,$b,$c).begininvoke()

$a.EndInvoke($r1); $b.EndInvoke($r2); $c.EndInvoke($r3) # wait
($a,$b,$c).Streams.Error # check for errors
($a,$b,$c).dispose() # cleanup

invoke-command를 사용하는 병렬 프로세스이지만 원격 파워셸이 작동하는 높은 프롬프트에 있어야 합니다.

invoke-command localhost,localhost,localhost { sleep 5; 'hi' } 

할당은 다음 식입니다.

if ($a = 1) { $a } 
$a = $b = 2

-1로 마지막 배열 요소 가져오기:

(1,2,3)[-1]

[void]를 사용하여 출력 폐기:

[void] (echo discard me)

어레이를 켜고 양쪽에서 $_:

switch(1,2,3,4,5,6) {
  {$_ % 2} {"Odd $_"; continue}
  4 {'FOUR'}
  default {"Even $_"}
}

모듈에서 변수 가져오기 및 설정:

'$script:count = 0
$script:increment = 1
function Get-Count { return $script:count += $increment }' > counter.psm1 # creating file

import-module .\counter.psm1

$m = get-module counter
& $m Get-Variable count
& $m Set-Variable count 33

모듈 기능 정의 참조:

& $m Get-Item function:Get-Count | foreach definition

commandinfo 개체와 호출 연산자를 사용하여 명령을 실행합니다.

$d = get-command get-date
& $d

동적 모듈:

$m = New-Module {
  function foo {"In foo x is $x"}
  $x=2
  Export-ModuleMember -func foo -var x
}

플래그 열거:

[flags()] enum bits {one = 1; two = 2; three = 4; four = 8; five = 16}
[bits]31

교체 연산자에 대한 알려진 코드가 거의 없습니다.

$number Substitutes the last submatch matched by group number.
${name} Substitutes the last submatch matched by a named capture of the form (?).
$$ Substitutes a single "$" literal.
$& Substitutes a copy of the entire match itself.
$` Substitutes all the text from the argument string before the matching portion.
$' Substitutes all the text of the argument string after the matching portion.
$+ Substitutes the last submatch captured.
$_ Substitutes the entire argument string.

체크포인트를 사용하여 중단을 극복하는 워크플로우의 데모입니다.창을 끄거나 재부팅합니다.그러면 PS를 다시 시작합니다.작업을 다시 시작하려면 get-job과 receiv-job을 사용합니다.

workflow test1 {
  foreach ($b in 1..1000) {
    $b
    Checkpoint-Workflow
  }
}
test1 -AsJob -JobName bootjob

Emacs 편집 모드.탭 완료를 누르면 모든 옵션이 한 번에 나열됩니다.아주 유용합니다.

Set-PSReadLineOption -EditMode Emacs

"get-"로 시작하는 명령어는 "get-"을 생략할 수 있습니다.

date
help

파싱 종료--%및 매개변수의 끝--오퍼레이터들.

write-output --% -inputobject
write-output -- -inputobject

와일드카드에서 탭 완료:

cd \pro*iles # press tab

내부에 cmdlet이 포함된 C# 모듈을 컴파일하고 가져옵니다(Osx에서도).

Add-Type -Path ExampleModule.cs -OutputAssembly ExampleModule.dll
Import-Module ./ExampleModule.dll

순서를 거꾸로 반복합니다. 단지 사용합니다.len범위의 반대쪽에 1이 있는 시퀀스의:

foreach( x in seq.length..1) { Do-Something seq[x] }

언급URL : https://stackoverflow.com/questions/893295/what-are-some-of-the-most-useful-yet-little-known-features-in-the-powershell-lan

반응형