답변:
PowerShell에서 공백 을 많이 건너 뛸 수 있습니다 . 그것이 필요하지 않을 것 같은 느낌이 든다면, 아마도 그렇지 않을 것입니다. 이것은 특히 비교에 유용합니다.
예:
$x-eq$i-and$x-ne9
vs.
$x -eq $i -and $x -ne 9
여러 결과가있을 수있는 단일 테스트 결과를 기반으로 스크립트를 분기해야하는 switch
경우 if 문과 일치하거나 이길 수 있습니다.
예 (스위치 대 if / else-타이) :
if($x%2-eq0){'even'}else{'odd'}
vs.
switch($x%2){0{'even'}1{'odd'}}
또는 (스위치 대 if / elseif / else-스위치가 15 씩 이깁니다) :
if($x%2-eq0){'even'}elseif($x%2-eq1){'odd'}else{'error'}
vs.
switch($x%2){0{'even'}1{'odd'}2{'error'}}
스위치가 실제로 위의 모듈로 연산과 같은 특정 수학 결과를 기반으로하는 경우 스위치를 완전히 어레이로 교체 할 수 있습니다. 여기서는 13자를 더 저장하고 원래의 두 옵션 if / else 문보다 짧습니다. ( 이 비트에 대해 Danko Durbic 에게 감사합니다 .)
('even','odd','error')[$x%2]
특정 명령, 특히 기존의 단축형 별칭이없는 명령을 많이 사용하려면 먼저 단일 문자 별칭을 설정하십시오.
예:
nal g Get-Random;g 10;g 10;g 10
vs.
Get-Random 10;Get-Random 10;Get-Random 10
('even','odd')[$x%2]
참고로
괄호 안에 변수를 정의하는 명령을 캡슐화하면 변수 정의를 다른 명령에 직접 공급할 수 있습니다.
예를 들어 $ x를 설정 한 후 다음과 같이 한 번의 $ x 값을 기준으로 $ y를 설정할 수 있습니다.
$y=($x=1)+1
이 대신에 :
$x=1;$y=$x+1
$ h를 설정하고 다음과 같이 출력 할 수 있습니다.
($h='Hello World!')
이 대신에 :
$h='Hello World!';$h
($x=New-Object Windows.Forms.Form).Controls.Add($t)
어레이가 주어지면 스위치는 루프처럼 작동 할 수 있습니다. 예를 들면 다음과 같습니다.
$FooBarMeh='a','b','c'
switch ($FooBarMeh)
{
'a'{'FOO'}
'b'{'BAR'}
default{'MEH'}
}
출력합니다 :
FOO
BAR
MEH
이것이 어디에서 유용할지는 확실하지 않지만 누군가에게 도움이 될 것으로 기대합니다.
ForEach-Object
와 a 가 필요할 때마다 편리 switch
합니다. 예를 들어 (실제로) 코드는 줄이 일치하는 정규 표현식에 따라 다른 작업을 수행 해야하는 텍스트 파일의 빠른 파서를 작성하는 데 매우 좋습니다.
switch -File $path
을위한 것 입니다
[math]::pow
곱셈으로 바꿉니다 . 대신에
[math]::pow($a,$b)
당신은 쓸 수 있습니다
"$a*"*$b+1|iex
이것은 정수 지수> = 0에서 작동합니다.
값 모음의 최대 값 또는 최소값을 찾고 싶습니까? 시도
(...|measure -ma).Maximum
또는
(...|measure -mi).Minimum
이미?
마지막 또는 첫 번째 항목을 정렬하고 사용하십시오.
(...|sort)[-1] # maximum
(...|sort)[0] # minimum
0
, 1
, 2
, 3
, 4
, 5
, 6
, 7
, 8
또는 9
, 대신의 알려진 길이를 작성하는 바이트를 저장할 것입니다 -1
.
안타깝게도 매개 변수와 달리 속성 / 메서드 (점으로 액세스하는 모든 것 .
)는 일반적으로 모호하지 않은 형태로 단축 할 수 없습니다.
그러나 특정 cmdlet은 속성 이름에서 작동 및 와일드 카드를 가지고, 그리고 잘 알려지지 않은 파라미터 세트가있다 할 수 %
와 ?
그 유용 할 수 있습니다.
일반적으로 scriptblock을 전달하고로 항목을 참조 $_
하지만 속성 이름을 사용하는 다른 형식이 있으며 와일드 카드를 허용합니다.
$o|select Le*
$o|%{$_.Length}
배열 자체의 속성 .Length
이기 때문에 일반적으로 배열에서 작동하는 v3 매직을 사용할 수없는 것과 같은 속성을 사용 Length
하면 위의 두 개를 사용하여 개별 멤버의 길이를 얻을 수 있습니다. 는 select
조금 짧은 비트에 제공됩니다.
그러나 %
속성 이름을 직접 가져 와서 해당 값을 반환 할 수 있습니다.
$a|% Length
와일드 카드로 단축 할 수 있습니다. 와일드 카드는 단일 속성 (또는 그 이후의 방법 등)으로 확인되어야하므로 해결되지 않은 멤버를 정확하게 나타내면 유용한 오류가 발생합니다.
의 경우에 Length
, Le*
일반적으로 짧다. 단일 문자열에서도이 방법은 속성을 사용하는 것보다 1 바이트 더 짧습니다.
$a.Length # 9 #(doesn't work on array)
$a|%{$_.Length} # 15
$a|% Le* # 8
그러나이 작업을 수행하면 상황이 더 악화 될 수 있습니다. 당신은 $a.Length*5
그것을 할 수 있지만 그것을 감싸 야 할 파이프 라인 표현식으로 할 수 있습니다 ($a|% Le*)*5
. 배열에 반대하는 경우 여전히 가치가 있지만 요점은 항상 직선 대체로 적합하지는 않습니다.
그것은 또한 메소드와 함께 작동하며 ()
, 전체 이름을 같은 길이로 만들지 만 때로는 랩 해야하는 것에 대해 위와 동일한 제한을 남길 수 있습니다 . 이 메소드에는 매개 변수를 사용하지 않는 과부하가 있어야합니다 (메서드 이름 뒤에 인수를 배치하여 인수를 전달할 수 있습니다).
$a.ToUpper() # 12
$a|% *per # 9
인수로 :
'gaga'-replace'g','r' # 21
'gaga'|% *ce g r # 16
-replace
연산자가 정규식 바꾸기를 수행 한다는 점에서 완전히 동일 하지는 않지만 문자열 바꾸기를 수행하는 경우 메소드를 사용하는 것이 더 짧을 수 있습니다. 문자열이 메서드 인수가 아닌 cmdlet 인수이므로 인용 할 필요가 없습니다.
?
(부분) 속성 이름을 가져 와서 "연산자"를 적용 할 수 있습니다 (스위치 매개 변수 형식). Where-Object
속성 이름이 충분히 길고 고유 한 경우 표준 스크립트 블록 방식을 사용하는 것보다 짧을 수 있습니다 .
$a|?{$_.Length-gt5} # 19
$a|? Le* -GT 5 # 14
($a|% Le*)-gt5 # 14 - Lengths, not objs
.ToString()
!
세미콜론과 줄 바꿈은 서로 바꿔 사용할 수 있습니다. 한 줄로 묶이지 않으면 골프 코드를 더 쉽게 읽을 수 있습니다. 길이는 여전히 동일합니다 (U + 000A를 PowerShell이 문제없이 처리하는 줄 바꿈으로 제공 한 경우).
Get
동사가 함축되어있다. 이것 Get-Frob
만으로도 짧아 질 수 있습니다 Frob
. 빈번한 경쟁자는 date
또는 random
입니다.
이 점에 유의 하지 않을 것이다 당신이 당신의 경로 (또는 충돌 다른 기본 프로그램)에서 GNU 유틸리티를 가질 수 있기 때문에 어떤 경우에는 제대로 작동합니다. 이 경우 명령 조회 순서는 Get-
제거 된 상태의 cmdlet을 고려하기 전에 기본 프로그램을 선호하는 것 같습니다 .
PS Home:\> date
Freitag, 15. November 2013 07:13:45
PS Home:\> $Env:Path += ';D:\Users\Joey\Apps\GnuWin32\bin'
PS Home:\> date
Fr Nov 15 07:14:13 W. Europe Standard Time 2013
nal g Get-Random
나중에 문자를 저장 하는 스크립트가 있습니다. nal g Random
스크립트를 변경 하면 스크립트가 무기한 중단됩니다 (또는 적어도 처리하는 데 시간이 많이 걸립니다-스크립트가 끝날 때까지 인내심이 없었지만 원래 형식보다 몇 배나 더 오래 걸립니다) 중단하기 전에).
Measure-Command
호출 (100 회 Get-Random
vs. random
)은 약 500 배 느립니다. 솔직히 전에는 몰랐습니다. 그러나 특히 반복 횟수가 많은 루프에서 명심하십시오. 그 존재는 (golfed 코드가없는 빠르고 짧은해야했다 그 존재가이 프로젝트 오일러 문제에 대한 답변 이틀 기다려야 싫어했다).
Get-Variable
대를 gv
과 유사한 비교를 얻었다.
Get-
. 길이가 4 자에 불과하기 때문에 런타임에 상당히 부풀어 오른다.
for
루프는 헤더에 0에서 3 개의 문이있을 수 있습니다.
끝없는 루프 :
for(){}
초기화 루프 :
for($n=0){}
초기화 및 종료 조건이있는 루프 :
for($n=0;$n-lt7){}
이러한 경우 항상 세 개의 명령문이 필요한 C와 유사한 언어와 달리 끝에 추가 세미콜론이 생략 될 수 있습니다 ( 언어 스펙 에 명시 적으로 명시되어 있으므로 구현 세부 사항은 아닙니다).
이것은 또한 while
조금 짧아집니다. 비교
while(...){}
과
for(;...){}
추가 보너스를 사용하면 for
추가 비용 (및 캐릭터 절약)없이 이전 줄 (있는 경우)에 붙일 수 있습니다 .
알고있는 배열을 할당 할 때는 두 개의 값만 가지므로 인덱싱을 사용하지 마십시오.
이 같은:
$a="apple","orange"
$a[0] # apple
$a[1] # orange
쉽게 이것으로 바꿀 수 있습니다 :
$a,$o="apple","orange"
$a # apple
$o # orange
배열의 첫 번째 요소 만 필요한 경우에도 유용합니다.
$a,$b=1..10
$a # 1
$b # 2..10
$a="apple";$o="orange"
길이는 동일합니다. 예를 들어 구분 기호가있는 문자열에 모든 요소를 넣은 다음 -split
(공백을 구분 기호로 사용하는 것이 가장 좋습니다 -split
) 단항으로 충분합니다.
문자열로 캐스팅 :
[string]$x
vs.
"$x"
이와 같이 문자열로 캐스팅하면 문자열 배열을 병합하는 대신 문자열 배열에 병합 할 수도 있습니다.
$a = @('a','b','c')
$a -join ' '
vs.
$a = @('a','b','c')
"$a"
문자열을 숫자 형으로 캐스팅 :
[int]$x [float]$x
vs.
+$x
또한 PowerShell은 항상 왼쪽 피연산자의 유형을 사용하여 식의 최종 유형과 적용 할 변환을 결정합니다.
'1'+2 -> '12'
1+'2' -> 3
불필요한 캐스트의 위치를 결정하는 데 도움이됩니다.
매개 변수의 전체 이름을 항상 제공 할 필요는 없으며 일부 매개 변수는 위치에 있다는 것을 잊지 마십시오.
Get-Random -InputObject (0..10)
... 자르기 가능 ...
Get-Random -I (0..10)
...이 경우 "I"이면 InputObject
이 명령의 다른 유효한 매개 변수 를 고유하게 식별하기에 충분합니다 .
당신은 그것을 더 다듬을 수 ...
Get-Random (0..10)
... InputObject
위치 매개 변수 이기 때문 입니다.
파이핑은 일반적으로 개체를 매개 변수로 공급하는 것보다 특히 괄호가 필요없는 경우보다 짧습니다. 난수 생성기를 더 잘라 봅시다 ...
0..10|Get-Random
명령을 변경할 수없는 경우에도 동일한 방법을 수행 할 수있는 다른 방법을 찾아보십시오. 위의 경우 다음을 수행 할 수 있습니다.
Get-Random 11
또는 다른 제안을 통합 *
Random 11
** 참고 : Get-
명령 이름을 생략 하면 런타임이 약 50,000 % 증가 할 수 있습니다. 명령이 한 번만 필요한 경우 나쁘지 않지만 긴 루프에서 조심해서 사용해야합니다. *
이것이 간단한 명령을 3 분의 1로 축소 할 수있는 방법입니다.
가짜 삼항 연산자. if
문장 에서 바로 할당 할 수 있습니다 .
$z=if($x-eq$y){"truth"}else{"false"}
그러나 2 요소 배열을 사용하고 테스트를 사용하여 색인을 작성할 수 있습니다. $ falsey 결과는 요소 0을, $ truthy 결과는 요소 1을 갖습니다.
$z=("false","true")[$x-eq$y]
NB. 실제로 배열 인덱싱을 수행하고 테스트 결과 정수로 캐스트 할 수 있는 값이 발생 하면 배열의 경계를 벗어난 항목을 요청하고 $ null을 돌려 !(test)
받고 강제 로 수행해야합니다. 옵션을 반대로하여 결과를 부울로 캐스트합니다.
$()
. 본질적으로 명령과 명령문으로 만들어진 파이프 라인을 표현식으로 사용하는 것이 구별되었습니다. 적어도 PowerShell 5에서는 사라진 것 같습니다.
그렇지 않으면 문자열이 필요한 연산자의 인수로 숫자를 사용할 때 숫자를 직접 사용할 수 있습니다. 비교
...-join'0'
vs.
...-join0
함께 작동 -split
합니다. 인수는 항상 문자열로 먼저 변환됩니다.
-replace
잘 작동 합니다.
-replace
또한 일치하는 항목을 제거하려는 두 번째 인수없이 작동합니다.
사용 $ofs
특별한 변수를 변경할 O utput F 의 ield S eparator 배열 stringifying 때 사용. 배열을 문자열로 여러 번 변환해야하는 경우에 유용합니다.
예를 들면 다음과 같습니다.
$a=1,2,3,4
$a-join',';$a-join','
$ofs=',';"$a";"$a"
2 개 + 저장 N 2에 문자를 -join
여기서 n은 분리의 길이이며, 추가 5+ 저장 N 의 3 -join
각 그 이후를.
자동 변수는 사실에 대한 논리 값과 거짓을 $true
하고 $false
있지만 논리 NOT 연산자를 사용하여 비슷한 결과를 얻을 수 !
및 정수 0과 1 (또는 0이 아닌 정수를.)
PS C:\Users\matt> !1
False
PS C:\Users\matt> !0
True
거의 모든 PowerShell 식을 부울로 평가할 수 있습니다. 따라서 특정 데이터를 평가하는 방법을 알고 있으면 부울을 얻을 수 있으며 명시 적으로 캐스팅 할 필요가 없습니다. 이를 수행 할 때 LHS 값을 알고 있어야합니다.
다른 예제가 있지만 캐스트를 수행하여 쉽게 테스트 할 수 있습니다.
PS C:\Users\matt> [bool]@(0)
False
$null
은입니다. 빈 문자열 (및 빈 문자열로 설정된 변수)이 잘못되었습니다. 그런 다음 FizzBuzz 에서 사용 된 것처럼 인덱싱을 배열로 바로 가기 위해 사용할 수 있습니다 (예 : if
/를 수행 할 때 else
) .
int
s를 사용하는 것이 더 짧습니다
bool
. 당신은 사용할 수 있습니다 0
및 1
단지뿐만 아니라. 암시 적 변환은 이와 관련하여 많은 도움이됩니다 (종종 특정 연산자로 강제 할 수 있음).
Invoke-Expression
그리고 Get-Random
또한 인수 대신 파이프 라인 입력을받을 수 있습니다.
이를 위해 iex
일부 표현식에 괄호를 저장할 수 있습니다.
iex 1..5-join'+' # won't work
iex(1..5-join'+') # does work, but has extra parentheses
1..5-join'+'|iex # doesn't need the parentheses
이 경우 random
일반적인 경우를 약간 최적화 할 수 있습니다.
random -mi 10 31 # gets a random integer between 10 and 30
10..30|random # much better :-)
(random 21)+10 # if needed in another expression that doesn't require extra
# parentheses
후자를 사용하는 방법은 단순히 목록에서 항목을 선택합니다. -c
인수는 하나의 선택보다 더 많은 수 있도록 부여 할 수 있습니다.
함수를 사용하는 대신 반복되는 스크립트 블록을 변수에 저장하십시오.
이 기능을 사용하여 함수를 변수로 다시 쓰는 것이 변수조차도 불필요하다는 것을 깨닫기 전에 Rock, Paper, Scissors 구현 에서 일부 문자를 저장하려고했습니다 . 그래도 실제로 동일한 코드를 여러 번 실행하는 다른 스크립트에 유용 할 수 있습니다.
function Hi{echo 'Hello, World!'};Hi
vs.
$Hi={echo 'Hello, World!'};&$Hi
params(...)
함수 정의가 저장하는 것보다 더 많은 공간을 차지합니다. 관련 : 할 수있을 때 filter
이상 사용하십시오 function
.
$args
필요를 피하기 위해 사용할 수 있습니다 params
; 즉 $x={$args[0]+2}
(또는 심지어 $x={2+"$args"}
); 경우에 따라 문자 또는 2를 저장할 수 있습니다. 이것을 여러 매개 변수에 대한 다른 트릭과 결합 할 수도 있습니다.$x={$a,$b=$args;$a+$b+3}
$s|% t*y
대신 [char[]]$s
문자열을 char 배열로 분할하는 데 사용할 수 있습니다 . TessellatingHeckler의 답변 에서 주어진 : equiv로 % t*y
확장합니다 | ForEach-Object -Method ToCharArray
. 의"$args".ToCharArray()
예를 들어
$s|% t*y
과
[char[]]$s
과
$s.ToCharArray()
$args
특히 유용합니다 .$args|% t*y
%
회원들에게 몇 가지 트릭을 사용 했지만 대부분의 내 골프는 ;-)를 특징으로합니다. 일반적인 기술이기도합니다. 필요한 속성 / 방법과 일치하는 문자 / 와일드 카드 조합을 찾아보십시오 (실제보다 짧음).
$s|% *per
for $s.toUpper()
and $s|% *wer
for $s.toLower()
. 나는 그것이 매우 깔끔하다는 것에 동의합니다.
1에서 10까지의 모든 짝수를 추가한다고 가정하십시오 ... 2+4+6+8+10=30
1..10|%{if($_%2-eq0){$o+=$_}};$o
부울 부정을 사용하여 단축 할 수 있습니다.
1..10|%{if(!($_%2)){$o+=$_}};$o
바이트를 저장하지만 대신 부울을 암시 적으로 int로 캐스팅하고 조건부를 누적기로 롤링하는 방법은 어떻습니까?
1..10|%{$o+=$_*!($_%2)};$o
이 예에서는 6 바이트를 저장합니다.
PowerShell에서 부동 소수점 숫자를 정수로 변환하는 것은 약간의 지뢰밭입니다. 기본적으로 변환은 Bankers Rounding 을 수행합니다. 소수점은 항상 소수를 잘라 내지 않고 더 작은 정수를 남기거나 사람들이 평소와 같이 항상 다음 숫자까지 0.5를 반올림합니다. 놀랍다
PS C:\> [int]1.5
2
PS C:\> [int]2.5
2
codegolf 계산을 중단하십시오. 다른 많은 일반 언어는 잘림을 수행하므로 골프 질문에는 잘림이 필요합니다. [Math]::Floor()
다음으로 가장 좋은 방법으로 도달 할 수는 있지만 양수에 대한 자르기와 동일하게 작동하지만 음수는 0에서 멀어집니다. [Math]::Truncate()
다른 언어의 기본 반올림에 따라 PS 동작을 가져와야하는 것이지만 많은 문자입니다.
소수점 뒤에 숫자를 바꾸는 정규 표현식은 몇 문자를 저장하는 데 도움이 될 수 있습니다.
[Math]::Truncate(1.5)
[Math]::Floor(1.5)
1.5-replace'\..*'
[Math]::Truncate($a)
[Math]::Floor($a)
$a-replace'\..*'
$a.split('.')[0] # literal character split, not regex pattern split
출력이 어떤 방식으로 반영되는지 에 관한 많은 예술적 과제 에 유용합니다 .
당신이 가지고 있다고 가정
$a=1,2,3,4,5
전통적인 반전 방법은 길고 지루하며 즉시 사용하기 위해 파이프 라인에 배열을 두지 않습니다.
[array]::reverse($a)
역순으로 배열에 직접 인덱싱하면 파이프 라인에 결과가 남지만 여전히 길기 때문에 몇 바이트를 절약 할 수 있습니다.
$a[($a.count-1)..0]
대신 루프를 시도하십시오
$a|%{$a[-++$i]}
PowerShell Core 6부터는 문자 범위를 사용할 수도 있습니다.
'a'..'z'
훨씬 더 번거로울 수있는
0..25|%{[char]($_+97)}
[char[]](65..90)
알파벳을 생성하는 편리한 방법이기도합니다