code

파일 이름에 대괄호 [ ]로 파일을 복사하고 * 와일드카드를 사용합니다.

starcafe 2023. 10. 20. 13:53
반응형

파일 이름에 대괄호 [ ]로 파일을 복사하고 * 와일드카드를 사용합니다.

Windows 7에서 PowerShell을 사용하고 있으며 한 폴더 구조에서 다른 폴더 구조로 여러 파일을 복사하는 스크립트를 작성하고 있습니다.일종의 컴파일 같은 거죠.lCopy-Itemcmdlet은 대괄호 [ ]가 일종의 와일드카드라고 생각합니다. 그리고 저는 어떤 이유로 대괄호를 벗어날 수 없습니다.

사용할 수 없습니다.-LiteralPath, 파일 이름에 날짜가 파일 이름의 일부로 포함되어 있고 날짜가 변경되기 때문에 별표 * 와일드카드를 사용하고 싶습니다.날짜가 버전 번호로 사용됩니다.

이 게시물은 도움이 되었지만 사각형 괄호를 벗어나는 눈금(괄호당 2배 또는 4배)은 없습니다.

오류가 발생하지 않습니다. PowerShell은 파일 이름을 잘못 입력한 것과 동일하게 동작합니다.

이것이 제가 작업하고 있는 구체적인 라인입니다.

#to Fusion Server
Copy-item -Path $FSG\$SW\0.RoomView.Notes\starter\"[RoomView] Versions explained*.pdf" -Destination $FSG\$containerFolder\$rootFolder\"Fusion Server"\

그리고 이게 전부입니다.

# Compiles the Fusion packet for distribution

###############################
###########Variables###########
###############################

#folder structure
$FSG = "F:\FSG"
$containerFolder = "Packet.Fusion for IT and AV Professionals"
$rootFolder      = "Fusion for IT and AV pros $(Get-Date -format “MM-dd-yyyy”)"
$subRoot1        = "Fusion Server"
$subRoot2        = "Scheduling Enhancement and Panels"
$subRoot2sub1    = "Scheduling Panels"
$subRoot3        = "SQL Server"

#source folders
$HW      = "0.Hardware"
$3SMDoc  = "0.Hardware\TPMC-3SM.Documentation"
$4SMDoc  = "0.Hardware\TPMC-4SM.Documentation"
$4SMDDoc = "0.Hardware\TPMC-4SM-FD.Documentation"
$730Doc  = "0.Hardware\TSW-730.Documentation"
$730OLH  = "0.Hardware\TSW-730.OLH"
$CENRVS  = "0.Hardware\CEN-RVS.Notes"

$ProjMgmt = "0.Project Management"

$SW            = "0.Software"
$RVLicensing   = "0.Software\0.RoomView.License"
$RVNotes       = "0.Software\0.RoomView.Notes"
$SQLLicensing  = "0.Software\database.SQL.Licensing"
$SQLNotes      = "0.Software\database.SQL.Notes"
$FRVMarketing  = "0.Software\Fusion RV.Marketing"
$FRVNetworking = "0.Software\Fusion RV.Networking"
$FRVNotes      = "0.Software\Fusion RV.Notes"


###############################
#create the directory structure
###############################

md -Path $FSG\$containerFolder -Name $rootFolder

cd $FSG\$containerFolder\$rootFolder
md "eControl and xPanels"
md "Fusion Server" #$subRoot1
md "Getting Started as a User"
md "Project Management"
md "RoomView Connected Displays"
md "Scheduling Enhancement and Panels" #$subRoot2
md "SQL Server" #$subRoot3

cd $FSG\$containerFolder\$rootFolder\$subRoot1
md "CEN-RVS"
md "Licenseing Information"
md "Networking"
md "Official Documentation"
md "Prerequisites, including powerShell script"
md "Product Info"
md "Requirements"
md "Tech Info"
md "Windows Authentication to Fusion RV"

cd $FSG\$containerFolder\$rootFolder\$subRoot2
md "Outlook Add-in"
md "Scheduling Panels" #$subRoot2sub1

cd $FSG\$containerFolder\$rootFolder\$subRoot2\$subRoot2sub1
md "TPMC-3SM"
md "TPMC-4SM"
md "TPMC-4SM-FD"
md "TSW-730"

cd $FSG\$containerFolder\$rootFolder\$subRoot3
md "Multi-database model only"
md "SQL Licensing"

cd $FSG\$containerFolder
#reset current folder


###############################
#copy the files
###############################

#Copy-Item -Path C:\fso\20110314.log -Destination c:\fsox\mylog.log

#To the root
Copy-item -Path $FSG\$ProjMgmt\starter\"Fusion Support Group Contact info*.pdf" -Destination $FSG\$containerFolder\$rootFolder\
Copy-item -Path $FSG\$containerFolder\"Fusion for IT and AV professionals release notes.txt" -Destination $FSG\$containerFolder\$rootFolder\

#to eControl and xPanels
Copy-item -Path $FSG\$SW\xpanel.Notes\starter\*.* -Destination $FSG\$containerFolder\$rootFolder\"eControl and xPanels"\

#to Fusion Server
Copy-item -Path $FSG\$SW\0.RoomView.Notes\starter\"[RoomView] Versions explained*.pdf" -Destination $FSG\$containerFolder\$rootFolder\"Fusion Server"\

대괄호를 벗어나면서도 와일드카드 파일 이름 부분을 계속 사용하려면 어떻게 해야 합니까?Copy-Itemcmdlet?

이런 상황에서는 괄호를 벗어나려면 따옴표 하나가 달린 더블 백틱을 사용해야 합니다.따옴표로 묶은 문자열을 사용할 경우 4중 백틱을 사용할 수도 있습니다.

따라서 코드의 고정 라인은 다음과 같습니다.

Copy-item -Path $FSG\$SW\0.RoomView.Notes\starter\'``[RoomView``] Versions explained*.pdf' -Destination $FSG\$containerFolder\$rootFolder\'Fusion Server'\

파일 경로 및 유선 문자 등에 대한 또 다른 좋은 자료는 다음 기사를 읽는 것입니다.파일 경로와 같은 것들을 말 그대로 가져가기


편집

@mklement0님께 감사드립니다. 이 불일치의 진정한 원인은 현재1 PowerShell에 있는 버그 때문입니다.이 버그로 인해 와일드카드 문자가 빠져나가고 기본값으로 백틱이 발생합니다.-Path다른 매개 변수와 다르게 동작하는 매개 변수(예:-Include그리고.-Filter매개 변수들.

@mklement0의 우수한 답변코멘트, 기타 답변에 대해 아래와 같이 확장하기:

상황에서 한 인용구와 두 개의 백틱이 필요한 이유를 더 잘 이해하기 위해 몇 가지 예를 살펴보도록 하겠습니다. (그리고 버그와 불일치를 강조하기 위해) 무슨 일이 일어나고 있는지 설명해 보겠습니다.

Get-Item(, cmdlet)Get-ChildItem,Copy-Item, 등), 처리합니다.-Path 이스케이프 와일드카드 문자와 이스케이프되지 않은 와일드카드 문자의 조합을 처리할 때 파라미터가 다르게 표시됩니다. *동시에**!

TLDR: 단일 인용구와 이중 백틱을 조합해야 하는 근본적인 이유는 기본 PowerShell 프로바이더가-Path와일드카드의 매개 변수 문자열입니다.이스케이프 문자에 대해 한 번 구문 분석하고 와일드카드 평가에 대해 두 번째 구문 분석하는 것으로 나타납니다.

이상한 결과를 보여주기 위해 몇 가지 예를 들어보겠습니다.

먼저, 두 개의 파일을 만들어 테스트해 보겠습니다.File[1]a.txt그리고.File[1]b.txt

"MyFile" | Set-Content '.\File`[1`]a.txt'
"MyFriend" | Set-Content '.\File`[1`]b.txt'

파일을 가져올 수 있는 여러 가지 방법을 시도해 보겠습니다.우리는 대괄호가[ ]와일드카드라서 백틱 캐릭터로 탈출해야 합니다

우리는 명시적으로 하나의 파일을 받으려고 노력할 것입니다.

먼저 따옴표로 묶은 단일 리터럴 문자열을 사용해 보겠습니다.

PS C:\> Get-Item 'File[1]a.txt'
PS C:\> Get-Item 'File`[1`]a.txt'

    Directory: C:\

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2019-09-06   5:42 PM              8 File[1]a.txt

PS C:\> Get-Item 'File``[1``]a.txt'

    Directory: C:\

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2019-09-06   5:42 PM              8 File[1]a.txt

따옴표로 묶은 문자열 하나의 경우 파일을 검색하는 데 필요한 백틱 하나만 사용해도 되지만 백틱 두 개도 사용할 수 있습니다.

따옴표로 묶은 문자열을 사용하면 다음을 얻을 수 있습니다.

PS C:\> Get-Item "File[1]a.txt"
PS C:\> Get-Item "File`[1`]a.txt"
PS C:\> Get-Item "File``[1``]a.txt"

    Directory: C:\  

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2019-09-06   5:42 PM              8 File[1]a.txt

예상대로 더블따옴표가 붙은 문자열의 경우, 작동하려면 백틱이 두 개 필요하다는 것을 확인할 수 있습니다.

이제 두 파일을 모두 검색하고 와일드카드를 사용하고자 합니다.

먼저 인용구 하나로 시작하겠습니다.

PS C:\> Get-Item 'File[1]*.txt'
PS C:\> Get-Item 'File`[1`]*.txt'
PS C:\> Get-Item 'File``[1``]*.txt'

    Directory: C:\

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2019-09-06   5:42 PM              8 File[1]a.txt
-a----       2019-09-06   5:49 PM             10 File[1]b.txt

따옴표 하나와 함께 와일드카드 문자가 있을 때는 뒷따옴표 두 가 필요합니다.하나는 브라켓을 탈출하는 것이고, 다른 하나는 와일드카드를 평가할 때 브라켓을 탈출하는 데 사용했던 백틱을 탈출하는 것입니다.

큰따옴표의 경우도 마찬가지입니다.

PS C:\> Get-Item "File[1]*.txt"
PS C:\> Get-Item "File`[1`]*.txt"
PS C:\> Get-Item "File``[1``]*.txt"
PS C:\> Get-Item "File```[1```]*.txt"
PS C:\> Get-Item "File````[1````]*.txt"

    Directory: C:\

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2019-09-06   5:42 PM              8 File[1]a.txt
-a----       2019-09-06   5:49 PM             10 File[1]b.txt

큰따옴표를 사용하면 와일드카드로 평가하는 것이 좀 더 상세합니다.이 경우에는 백틱 4세트가 필요합니다.큰따옴표를 사용할 경우에는 브라켓을 탈출하기 위해 백틱 2개와 스타 와일드카드를 평가할 때 탈출 캐릭터를 탈출하기 위해 백틱 2개가 필요합니다.


편집

@mklement0이 언급한 바와 같이, 이 동작은-Path매개 변수가 일치하지 않으며, 다음과 다르게 동작합니다.-Includeparameter(대괄호를 제대로 빠져나오려면 백틱을 한 번만 사용하면 됩니다).이는 이후 버전의 PowerShell에서 "수정"된 것일 수 있습니다.


1 Windows PowerShell v5.1/PowerShell Core 6.2.0-preview.3 기준

개요 및 몇 가지 배경 정보:

  • 와일드카드 표현식일부해석하려는 문자를 효과적으로 회피하려면 대상 cmdlet(기본 PowerShell 드라이브 공급자)에서 볼 수 있듯이 -escape해야 합니다.

  • (backtick)은 이중 따옴표가 있는 문자열()"..." 및 비 따옴표가 없는 명령어 인수(대부분의 경우 이중 따옴표가 있는 문자열처럼 동작함)에서도 이스케이프 문자로 사용되기 때문에 까다로울 수 있습니다.

참고: 질문의 시나리오에서는 다음을 사용할 수 없습니다.-LiteralPath, 그러나 구체적이고 문자 그대로의 경로알고 있는 경우에는 (PowerShell Core에서 줄여서 사용할 수 있음)을 사용하는 것이 가장 좋습니다. 이 답변을 참조하십시오.

PowerShell 드라이브 공급자 관련 cmdlet의 와일드카드 지원 매개 변수에 인수를 전달할 때(Get-ChildItem,Copy-Item,Get-Content, ...) 그리고 당신이 원하는 것은[그리고.]문자 집합/범위 표현이 아닌 말 그대로 취급:

  • 문자열 리터럴 표현:

    • 'file`[1`].txt'

      • `내부에 그대로 보존되어 있는 차.'...', 그래서 목표 cmdlet은 의도한 대로 그들을 봅니다.
    • "file``[1``].txt"

      • ``, 즉, 내부에 배가 필요합니다."..." 한 개도 보존하기 위하여 `결과 문자열(첫번째)로 `는 (이중 quoted) 문자열 내부 탈출 문자이고, 두 번째는`통과하기 위해 탈출하는 캐릭터입니다).
    • file``[1``].txt(식에서 작동하지 않고 명령어 인수로만 작동)

      • 따옴표로 묶지 않은 명령어 인수의 경우 Ditto, (대부분의 경우) 다음과 같이 동작합니다."..."
    • 주의 사항: 버그 인해 - GitHub 문제 #7999 참조 - 혼합(탈출되지 않음) 또는 이스케이프된 상태에서 후자를 이중으로 이스케이프해야 합니다(대상 cmdlet/provider에서 볼 있음).

      • 리터럴 파일 이름을 일치시키려면file[1].txt일치하는 와일드카드 패턴으로[그리고.] 그대로 특별한 캐릭터를 담고 있으면서도*(모든 문자의 실행과 일치), 예상되는 대신'file`[1`]*', 를 사용해야 할 것입니다.'file``[1``]*'(sic); 이중 quoted 또는 회피되지 않은 논쟁을 통해 4중 백틱을 효과적으로 사용해야 합니다."file````[1````]*"/file````[1````]*- 자세한 내용은 이 답변을 참조하십시오.

      • 와 함께 와일드카드를 직접 사용합니다.-like연산자는 영향을 받지 않습니다.

        • 'a[b' -like 'a`[*'정확하게는 - 입니다.$true,
        • 반면에.'a[b' -like 'a``[*'- 당연하게도 - 잘못된 패턴에 대해 불만을 제기합니다.
      • 마찬가지로 모수 및 는 영향을 받지 않습니다.

      • -Filter 다른 규칙에 따라 재생합니다.[...]구조물이 전혀 지원되지 않기 때문입니다.[그리고.]chars.는 항상 리터럴(literal)로 간주됩니다(다시, 이 답변 참조).

  • 변수를 통해 프로그래밍 방식으로 경로 문자열을 빠져나가려면 다음을 사용합니다.

      $literalName = 'file[1].txt'
      $escapedName = [WildcardPattern]::Escape($literalName) # -> 'file`[1`].txt'
    

나는 이것을(를)

 Copy-Item  $file.fullname.replace("[", "``[").replace("]", "``]") $DestDir

파워셸이 자동으로 파일명을 탭으로 완성하는 방법이 보통 가장 좋은 방법입니다.

예:

copy-item '.\file`[test`].txt'

PowerShell v 2.0 이상에서 사용할 이스케이프 문자는 백슬래시입니다.예를 들어 시스템 Center Orchestrator의 Exchange 관리 PowerShell cmdlet 작업에서 얻은 출력의 일종인 "[Servername: QA01]" 문자열에서 괄호를 제거하려면 다음 논리를 사용합니다.

$string -replace '\[','' -replace '\]',''
>Servername: QA01

이거 좀 이상하네요.단일 인용문을 사용해야 합니다(일반적으로 PowerShell에서는 '이를 정확히 기록된 대로 평가한다'는 의미이므로 매우 이상한 구문입니다).

이것을 스스로 알아내지 못한다고 해서 기분 나쁘게 생각하지 마세요, 이것은 매우 이상한 구문입니다.

보아하니, 사각형은 탈출하기 위해 이중 백틱이 필요한 것 같은데, 이는 이례적인 일입니다.여기 참고하세요.

그게 안 되는 게 확실해요?저는 그것을 몇 번 본 적이 있습니다.

편집: 네, 효과가 있습니다. 백틱 대신 큰 따옴표를 사용했습니다.

큰따옴표는 아포스트로피 문자 위에 Enter 키 옆에 있습니다.백틱은 이스케이프 키 바로 아래에 있으며, 키를 틸드와 공유합니다. ~.

다른 항목이 일치하지 않을 경우 괄호 대신 ?를 사용할 수 있습니다."a[h-j]"라는 이름의 파일로 디렉터리 "foo"에 복사:

 copy-item a?h-j? foo 

Get-ChildItem을 사용하여 와일드카드를 수행한 다음 Copy-Item에 결과를 파이핑하고 LiteralPath를 사용하는 것이 가능하다고 생각합니다.

Get-ChildItem $FSG\$ProjMgmt\starter\"Fusion Support Group Contact info*.pdf" | %{Copy-Item -LiteralPath $_.FullName -Destination "$FSG\$containerFolder\$rootFolder\"}

이 작업을 자주 수행하지만 경로에 있는 변수의 경우에는 수행하지 않습니다. 스크립트 블록 내부의 변수가 올바르게 범위를 지정하려면 무언가를 해야 할 수도 있습니다.일반적으로 이 방법을 사용하면 Copy-Item 또는 Move-Item 경로에서 와일드카드를 사용하지 않으므로 LiteralPath가 작동할 수 있습니다.특히 파일 경로에 특수 문자가 어디에 있거나 무엇이 있는지 모르는 경우에는 탈출 문자가 필요 없습니다.

하나의 옵션은 레거시를 사용하여 파일 이름을 가져오는 것입니다.dir, 당신이 사용할 수 있게 해 줄 것입니다.*와일드카드 문자이지만 대괄호를 "블랍"하려고 하지 않습니다.그런 다음 해당 목록을 다음으로 전송합니다.move-item-literalpath.

cmd /c dir *]* /b |
  foreach { Move-Item -LiteralPath $_ -Destination <destination path> }

사이에 차이가 있습니다.'그리고.`:

  • 첫 번째는 키의 비시프트 문자인 하나의 따옴표입니다.
  • 두 번째는 사용하는 줄 알았는데 사용하지 않았던 백틱입니다.그것은 키에 있는 임시 문자입니다.

작동 내용:

# to Fusion Server
Copy-item -Path $FSG\$SW\0.RoomView.Notes\starter\'``[RoomView``] Versions explained*.pdf' -Destination $FSG\$containerFolder\$rootFolder\"Fusion Server"\

언급URL : https://stackoverflow.com/questions/21008180/copy-file-with-square-brackets-in-the-filename-and-use-wildcard

반응형