Copy file with square brackets [ ] in the filename and use * wildcard

powershell rename files with square brackets
remove parentheses from filenames
powershell rename file with brackets
powershell match square brackets
powershell path with square brackets
powershell special characters in filename
powershell replace square brackets
powershell rename files with special characters

I'm using PowerShell on Windows 7, and writing a script to copy a bunch of files from one folder structure to another. Kind of like compiling. The PowerShell Copy-Item cmdlet thinks that square brackets, [ ], are wildcards of some kind, and I am not able to escape them for some reason.

I can't use -LiteralPath, because I want to use an asterisk * wildcard since the filename has a date as part of the filename, and the date changes. The date is used as a version number.

This post was helpful, but no amount of ticks (2x or 4x per bracket) escapes the square brackets.

I am not receiving an error; PowerShell behaves the same as if I entered in the wrong filename.

This is the specific line I'm working on:

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

And this is the whole thing:

# 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"\

What can I do to escape the square brackets and still use a wildcard filename part of the Copy-Item cmdlet?

In this situation, you have to use double-backticks with single quotes in order to escape the brackets. You can also use quadruple backticks when you use double quoted strings.

So the fixed line of code is:

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

Another good resource on file paths and wired characters etc. is to read this article: Taking Things (Like File Paths) Literally


EDIT

Thanks to @mklement0 for highlighting that the true cause of this inconsistency is because of a bug currently in PowerShell1. This bug causes escaping of wildcard characters, as well as backticks with the default -Path parameter to behave differently than other parameters e.g. the -Include and -Filter parameters.

To expand on @mklement0's excellent answer, and comments, and other answers below:

To better understand why we need single quotes and two back ticks in this situation; (and to highlight the bug and inconsistencies) let's run through some examples to demonstrate what is going on:

Get-Item, and associated cmdlets (Get-ChildItem, Copy-Item, etc.), handle the -Path parameter differently when dealing with a combination of escaped wildcard characters and unescaped wildcard characters *at the same time***!

TLDR: The underlying reason that we need a combination of single quotes and double backticks is how the underlying PowerShell provider parses the -Path parameter string for wildcards. It appears to parse it once for the escape characters, and a second time for the evaluation of the wildcard.

Let's go through some examples to demonstrate this odd outcome:

First, let's create two files to test with called File[1]a.txt and File[1]b.txt

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

We'll try different ways to get the file. We know that Square brackets [ ] are wildcards, and so we need to escaped them with the backtick character.

We will try to get one file explicitly.

Let's start by using single quoted literal strings:

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

For single quoted strings, one backtick is all that is required to retrieve the file, but two backticks also work.

Using Double quoted strings we get:

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

For double quoted strings, as expected, we can see that we need two backticks to make it work.

Now, we want to retrieve both files and use a wildcard.

Let's start with single quotes:

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

With the single quotes, when we have a wildcard character, we need two sets of backticks. One to escape the bracket, and a second backtick to escape the backtick that we used to escape the bracket when the wildcard is evaluated.

Similarly for double quotes:

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

With double quotes it's a little more verbose to evaluate with a wildcard. In this case, we need four sets of back ticks. For double quotes we need two backticks to escape the bracket, and another two backticks to escape the escape characters once it comes to evaluation of the star wildcard.


EDIT

As @mklement0 mentions, this behavior with the -Path parameter is inconsistent, and behaves differently than the -Include parameter, where only a single backtick is required to properly escape the brackets. This may be "fixed" in a later version of PowerShell.


1 As of Windows PowerShell v5.1 / PowerShell Core 6.2.0-preview.3

powershell Copy file with square brackets [ ] in the filename and use , powershell Copy file with square brackets [ ] in the filename and use * wildcard? copy-item '.\file`[test`].txt'. The way that Powershell automatically tab-completes� Kind of like compiling. The PowerShell Copy-Item command Copy-Item cmdlet thinks that square brackets, [ ], are wildcards of some kind, and I am not able to escape them for some reason. I can't use -LiteralPath, because I want to use a an asterisk * wildcard since the filename has a date that's as part of the name filename, and it the date changes.

I use this:

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

Powershell Bug in copy/move/rename when filename contains , Unless you use -LiteralPath , square brackets cause real problems with character escaping. The wildcard pattern matching that Get-ChildItem does means that if it gets [ab].txt as the path, then it will look for files named a.txt and b.txt . Suppose, the file extension, the total number of characters of a file and some characters of the file are known, then you can use this wildcard to search the file. The command will search the file which has the extension ‘.PNG’ , the word ‘pic’ is at the end of the filename and filename is six character long.

The way that Powershell automatically tab-completes the filename is usually the best way,

Example:

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

10 Practical Examples Using Wildcards to Match Filenames in Linux, How to Match Filenames Using Wildcards in Linux This command matches all files with names starting with l (which is the prefix) and This example shows another use of * to copy all filenames prefixed with users-0 with l followed by any of the characters in the square bracket but ending with st.sh . Match Characters in Filenames How to Negate a Set of Characters in Linux. 10. You can as well negate a set of characters using the ! symbol. The following command lists all filenames starting with users-i, followed by a number, any valid file naming character apart from a number, then a lower or upper case letter and ends with one or more occurrences of any character.

On PowerShell v 2.0 and up the escape character to use is the backslash. For example, if we want to remove the brackets from this string "[Servername: QA01]" which is the sort of output we get from the Exchange Admin PowerShell cmdlet activity in System Center Orchestrator, we use the following logic:

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

This is pretty weird. See, you have to use a single-quote (which normally implies in PowerShell 'evaluate this precisely as written', so this is very odd syntax).

Don't feel bad for not figuring this out on your own, this is very odd syntax.

File and Directory Wildcards, File and Directory Wildcards When you have a number of files named in series ( for example You can use this to save typing for a single filename (for example, al* for Square brackets can surround a choice of characters you'd like to match. hi can anybody help me out in solving this issue. i want to copy files which have wildcards in the filename from one directory to another and for this iam using a foreach loop container with a file system task inside it ,i defined the source variable in the variable mapping in foreach loop container (i.e the same source variable that iam using in File system task) and i also defined the

Apparently, square brackets need double-backticks to escape, which is unusual. Reference here.

You're sure that doesn't work? I've seen it referred to a few times.

Edit: Yes, it works, you used double quotes instead of backticks.

Double quote is above the apostrophe character, next to the Enter key. Backtick is right underneath the Escape key, sharing the key with the tilde, ~.

File with square brackets in name not extracted by tar, Quoting the filename and using the --no-wildcards flag will suppress Replace square brackets with the wildcard characters (such as ? or * ),� Ok, the file name today is called BluesFinal-EmeaMortgages_3 1_Oct_2014 _865841515.xlsx" and the last 9 numerals change on a daily basis and the other Excel file I have to copy from is called "BluesWIPandBvGVariance-EM EAMortgage s_30_Oct_2 014_182639 827" where the last 9 numerals also change on a dilay basis. They are both opened via Outlook

How To Use Bash Wildcards for Globbing?, You can use glob patterns for filenames matching but also as part of a What is the Bash Brace Expansion and the Curly Brackets Wildcard {}?; Detailed Examples & FAQ. How to copy the files from the current directory to a subdirectory The square brackets matches any one of the enclosed characters. This code will move all the files (containing the search pattern in the file name) one level up the hierarchy. For example, Let's say that all your 't_1' files are stored in /Home/Desktop/ directory. Then just go to /Home/ from terminal and execute this command. All the 't_1' files will be moved from /home/Desktop/ to /home/ directory.

Problem with Powershell script using a path with square bracket , Problem with Powershell script using a path with square bracket containing a dash When run as a script from a batch command via the powershell -File There's some kind of a bug in ps5 with literalpath and wildcards. If I copy the directory and contents and rename said directory and contents with an� Re: Use TextBox In Closed File For Partial File Name. OkSo I changed a few things around. But still have the same problem. I have a column with one number in each row. That number is part of an adobe file name (changed from a ms word document as originally posted). I want to use that number to find the file and attach it to an email.

Using wildcard filenames in Snowflake COPY INTO command , Bracketed characters [ ] – matches any occurrence of character enclosed in the square brackets. It is possible to use different types of� I use 7 distinct arguments combined between my two tar processes here. The most important one is listed here first: The most important one is listed here first: - stdout/stdin - this informs tar that it will be streaming either its input or output to or from stdin/stdout which it will interpret correctly depending on whether or not it is

Comments
  • I would +1 this, but I don't have enough reputation :(
  • If this fixed your issue, you can Accept the answer.
  • Agree hal9256. Not Cool OP copied the essence of your answer into his own and marks that as correct. Not cool at all.
  • @mklement0 You are right, with single quotes, a single escape character is sufficient to escape the brackets. In this case, OP also wanted to have a normal non-escaped wildcard character apply. In this case you need two sets of escape characters for it to work. I have edited my answer to better illustrate what's going on.
  • @HAL9256: You are correct (+1): Due to a bug - see this GitHub issue - mixing (unescaped) ? or * with escaped [ and ] requires the latter to be doubly escaped (as seen by the target cmdlet / provider). There is absolutely no reason for this obscure behavior (I had actually run into this). The bug must be in the provider code, because wildcards themselves function correctly: 'a[b' -like 'a`[*' is $true, and 'a[b' -like 'a``[*' - rightfully - complains about an invalid pattern.
  • Actually I did wind up figuring it out on my own, and I posted the answer down below. but I don't have enough reputation or the system won't allow me to move it up, so other people are promoting other answers, even though I answered my own question. The system sure didn't like something like me with no points answering my own question, lol
  • Yeah, answering your own problem is pretty much a recipe for downvotes here. Usually it's best to pick an answer closest to your own and call it a day.
  • Actually, no yetanotherrandomuser, it doesn't appear you answered your own question. hal9256 provided an answer to this question almost 22 hours earlier that contains the essence of your answer. To my mind, the community doesn't like what was done and is using it's voting power to illustrate as such.
  • Thanks for this answer foxdeploy. This helped my reason for coming to this page.
  • \ (backslash) is the escape character in regular expressions, which is unrelated to PowerShell - you need it here to escape the [ and ] regex metacharacters. PowerShell's escape character is ` (backtick), in multiple contexts: double-quoted strings and unquoted command arguments, line continuation and wildcard patterns. It is the latter that the question is about: how to use [ and ] literally in a filesystem path that is interpreted as a wildcard pattern. You're answering a different question.
  • Neither 2x nor 4x ' characters escape the [ or ] for me. Am I using it wrong? I have tried the source path within " " and without " "
  • Is there more than 1 type of tick? I've only got the one as far as I can tell.... By "not working" I mean that the file does not get copied.
  • As an aside (of little consequence): As evidenced by the OP's own answer, it was the single quote (apostrophe) that was mistaken for the backtick.
  • Just to add, that with single quotes, a single escape character is sufficient to escape the brackets. If you want to have a normal non-escaped wildcard character also apply, you need two sets of escape characters for it to work. Please see my edits to my answer for a more detailed reaon.