큰 따옴표로 묶인 문자열에서 객체의 속성을 어떻게 사용할 수 있습니까?


97

다음 코드가 있습니다.

$DatabaseSettings = @();
$NewDatabaseSetting = "" | select DatabaseName, DataFile, LogFile, LiveBackupPath;
$NewDatabaseSetting.DatabaseName = "LiveEmployees_PD";
$NewDatabaseSetting.DataFile = "LiveEmployees_PD_Data";
$NewDatabaseSetting.LogFile = "LiveEmployees_PD_Log";
$NewDatabaseSetting.LiveBackupPath = '\\LiveServer\LiveEmployeesBackups';
$DatabaseSettings += $NewDatabaseSetting;

문자열에서 속성 중 하나를 사용하려고하면 명령을 실행합니다.

& "$SQlBackupExePath\SQLBackupC.exe" -I $InstanceName -SQL `
  "RESTORE DATABASE $DatabaseSettings[0].DatabaseName FROM DISK = '$tempPath\$LatestFullBackupFile' WITH NORECOVERY, REPLACE, MOVE '$DataFileName' TO '$DataFilegroupFolder\$DataFileName.mdf', MOVE '$LogFileName' TO '$LogFilegroupFolder\$LogFileName.ldf'"

유효하지 않은 $DatabaseSettings의 값 대신 의 값을 사용하려고 $DatabaseSettings[0].DatabaseName합니다.
내 해결 방법은 새 변수에 복사하는 것입니다.

큰 따옴표로 묶인 문자열에서 객체의 속성에 직접 액세스하려면 어떻게해야합니까?

답변:


166

큰 따옴표로 묶인 문자열로 변수 이름을 묶으면 해당 변수의 값으로 대체됩니다.

$foo = 2
"$foo"

된다

"2"

작은 따옴표를 사용하지 않으려면 :

$foo = 2
'$foo'

그러나 속성에 액세스하거나 큰 따옴표로 묶인 문자열의 변수에 인덱스를 사용하려면 해당 하위 식을 $()다음 으로 묶어야합니다 .

$foo = 1,2,3
"$foo[1]"     # yields "1 2 3[1]"
"$($foo[1])"  # yields "2"

$bar = "abc"
"$bar.Length"    # yields "abc.Length"
"$($bar.Length)" # yields "3"

PowerShell은 이러한 경우에만 변수를 확장합니다. 인덱스, 속성 또는 전체 계산을 포함하여 더 복잡한 식을 강제로 평가하려면 하위 $( )식 연산자로 묶어야합니다. 그러면 내부식이 평가되고 문자열에 포함됩니다.


나뿐만 아니라 단지 CONCATENATE 문자열 내가 처음에 피하려고 한 수 있으므로 경우에 작동하지만 궁금
ozzy432836

2
@ ozzy432836 물론 가능합니다. 또는 형식 문자열을 사용하십시오. 그것은 일반적으로별로 중요하지 않으며 개인적인 선호도에 달려 있습니다.
Joey

15

@Joey가 정답을 가지고 있지만 왜 평가를 강제해야하는지에 대해 조금 더 추가하기 위해 다음을 사용하십시오 $().

예제 코드에는 PowerShell 제작자가 확장을 단순한 변수 참조로 제한하고 속성에 대한 액세스도 지원하지 않기로 선택한 이유를 나타내는 모호성이 포함되어 있습니다 (제외 : 문자열 확장은 ToString()개체 에서 메서드를 호출하여 수행됩니다. "이상한"결과를 설명 할 수 있습니다.)

명령 줄의 맨 끝에 포함 된 예제 :

...\$LogFileName.ldf

객체의 속성이 기본적으로 확장 된 경우 위의 내용은

...\

이 참조하는 개체가 이후 $LogFileName라는 속성이없는 것 ldf, $null(또는 빈 문자열) 변수를 대체 할 것입니다.


1
좋은 발견. 사실 : 완전히 확인 자신의 문제가 무엇인지하지만 문자열 냄새가 나쁜 내에서 속성에 액세스하려고하지 않았다
조이

감사합니다! Johannes 문자열의 속성에 액세스하는 것이 왜 나쁜 냄새가 난다고 생각합니까? 그것이 어떻게 이루어 졌다고 제안합니까?
caveman_dick

원시인 : 잠재적 인 오류 원인으로 내 눈을 사로 잡은 것이 었습니다. 당신은 확실히 그것을 할 수 있고 이상한 것은 아니지만 $ () 연산자를 생략하면 작동하지 않기 때문에 "Fail"이라고 외칩니다. 따라서 내 대답은 내가 볼 수있는 첫 번째 가능한 실패 원인을 사용하여 당신의 poblem이 무엇인지에 대한 교육적 추측이었습니다. 그렇게 생겼 으면 미안하지만 그 댓글은 모범 사례를 언급하지 않았습니다.
Joey

내가 거기에서 걱정하게해서 좋았어! ;) 처음 powershell을 사용하기 시작했을 때 문자열의 변수가 조금 이상하다고 생각했지만 매우 편리합니다. 구문 도움말을 찾을 수있는 확실한 위치를 찾지 못했습니다.
caveman_dick

9

@Joey는 좋은 대답을 가지고 있습니다. String.Format에 상응하는 .NET 모양의 또 다른 방법이 있습니다. 객체의 속성에 액세스 할 때 선호합니다.

자동차에 관한 사항 :

$properties = @{ 'color'='red'; 'type'='sedan'; 'package'='fully loaded'; }

개체 만들기 :

$car = New-Object -typename psobject -Property $properties

문자열 보간 :

"The {0} car is a nice {1} that is {2}" -f $car.color, $car.type, $car.package

출력 :

# The red car is a nice sedan that is fully loaded

네, 특히 .net 코드에 익숙하다면 더 읽기 쉽습니다. 감사! :)
caveman_dick

3
형식 문자열을 처음 사용할 때주의해야 할 점이 있는데, 이는 종종 식을 괄호로 묶어야한다는 것입니다. 당신은, 예를 들어 간단하게 쓸 수 write-host "foo = {0}" -f $fooPowerShell을 처리합니다 이후 -f는 AS ForegroundColor에 대한 매개 변수 write-host. 이 예에서는 write-host ( "foo = {0}" -f $foo ). 이것은 표준 PowerShell 동작이지만 주목할 가치가 있습니다.
andyb

현명하게 말하면 위의 예는 "문자열 보간"이 아니라 "복합 서식"입니다. Powershell은 C # 및 VB.NET이 기본 프로그래밍 언어 인 .NET에 불가분의 관계로 바인딩되어 있으므로 "문자열 보간"및 "보간 문자열"(및 유사 항목)이라는 용어는 해당 용어에서 발견되는 새로운 $ 접두어 문자열에만 적용되어야합니다. 언어 (C # 6 및 VB.NET 14). 이러한 문자열에서 매개 변수 표현식은 숫자 매개 변수 참조 대신 문자열에 직접 삽입되며 실제 표현식은에 대한 인수가됩니다 String.Format.
Uber Kluger

@andyb, 형식 문자열 "gotchas"관련. 이것은 실제로 Expression 모드 와 Argument 모드 의 차이점입니다 ( about_Parsing 참조 ). 명령은 토큰 (의미있는 문자열을 형성하는 문자 그룹)으로 구문 분석됩니다 . 공백은 병합되지만 무시되는 토큰을 구분합니다. 명령의 첫 번째 토큰이 숫자, 변수, 명령문 키워드 (if, while 등), 단항 연산자, {등인 경우 구문 분석 모드는 Expression그렇지 않은 경우 Argument(명령 종결 자까지)입니다.
Uber Kluger

8

설명서 참고 사항 : Get-Help about_Quoting_Rules문자열 보간을 다루지 만 PSv5부터는 심층적이지 않습니다.

보완하기 위해 조이의 도움이 대답을실용적인 요약 PowerShell을의의 문자열 확장 에서 (문자열 보간 큰 따옴표 (문자열 "..."), 이중 인용을 포함하여 여기 - 문자열 ) :

  • 문자열에 직접 포함 된 경우 $foo, $global:foo(또는 $script:foo, ...) 및$env:PATH (환경 변수 )와 같은 참조 만 인식됩니다. 즉, 뒤에 오는 내용에 관계없이 변수 참조 자체 만 확장됩니다."..."

    • 하기 위해 변수 이름을 명확하게 문자열에 다음 문자에서 묶어야 {하고} ; 예 : ${foo}.
      변수 이름이 뒤에있는 경우에 특히 중요하다 :PowerShell을 달리 사이에있는 모든 생각하는 것처럼, $그리고 범위 일반적으로하는 보간 원인 지정자를 실패 ; 예 : 중단되지만 의도 한대로 작동합니다. (대안 적으로, 을 -escape : ).:"$HOME: where the heart is.""${HOME}: where the heart is."
      `:"$HOME`: where the heart is."

    • a $또는 a "리터럴 로 처리하려면 이스케이프 문자를` 접두사로 붙 입니다. ( 백틱 ); 예 :
      "`$HOME's value: `"$HOME`""

  • 사용을 포함하여 다른 것을 위해, 배열 첨자 와 개체 변수의 접근 속성을 , 당신은해야한다 의 표현 둘러싸$(...)표현식 연산자를 (예를 들어, "PS version: $($PSVersionTable.PSVersion)"또는 "1st el.: $($someArray[0])")

    • 사용 $(...)도하면 큰 따옴표 문자열 (예를 들어,에 전체 명령 라인의 출력을 포함 할 수 있습니다 "Today is $((Get-Date).ToString('d')).").
  • 보간 결과가 기본 출력 형식과 반드시 ​​동일하지는 않습니다 (예를 들어 기본 포맷터와 관련된 변수 / 하위 표현식을 콘솔에 직접 인쇄 한 경우 표시되는 내용, 참조 Get-Help about_format.ps1xml).

    • 배열을 포함한 컬렉션 은 요소의 문자열 표현 사이에 단일 공백배치 하여 문자열로 변환됩니다 (기본적으로 설정으로 다른 구분 기호를 지정할 수 있음 $OFS). 예, "array: $(@(1, 2, 3))"yieldsarray: 1 2 3

    • 인스턴스 다른 유형 (자체 컬렉션없는 모음 요소를 포함)가있다 하여도 캐릭터 라인 발신 IFormattable.ToString()와 방법 불변 문화 인스턴스의 유형이 지원하는 경우, IFormattable인터페이스 [1] , 또는 호출 .psobject.ToString()되는 대부분의 경우에 단순히 호출한다.ToString() 의미있는 표현을 제공 할 수도 있고 제공하지 않을 수도 있는 기본 .NET 유형의 메소드 [2] : (기본이 아닌) 유형이 .ToString()메소드를 구체적으로 재정의하지 않는 한 전체 유형 이름 (예 : "hashtable: $(@{ key = 'value' })"yields hashtable: System.Collections.Hashtable) 만 얻을 수 있습니다.

    • 콘솔에서와 동일한 출력얻으 려면 원하는 경우 하위 표현식과 파이프를 사용Out-String 하고 적용 .Trim()하여 선행 및 후행 빈 줄을 제거하십시오. 예
      "hashtable:`n$((@{ key = 'value' } | Out-String).Trim())":

      hashtable:                                                                                                                                                                          
      Name                           Value                                                                                                                                               
      ----                           -----                                                                                                                                               
      key                            value      

[1] 아마도이 놀라운 행동은 문화에 민감한 표현을 지원하는 유형의 $obj.ToString()경우 현재 문화에 적합한 표현을 산출하는 반면 "$obj"(문자열 보간)은 항상 문화 불변 표현을 생성 한다는 것을 의미합니다 . 이 대답 을 참조하십시오 .

[2] 주목할만한 재정의 :
* 이전에 논의 된 컬렉션의 문자열 화 (예 :와 같은 것이 아니라 공백으로 구분 된 요소 목록 System.Object[]).
* 빈 문자열이 아닌 해시 테이블 과 유사한[pscustomobject] 인스턴스 표현 ( 여기에 설명 됨 ) .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.