Whisperer
2007-03-27 13:55:06 UTC
After reading around about square brackets in names of files I can
understand
the need for using escape characters when referring to such files but
the comments I have found always assume the string for the file name
is
entered manually.
This is no use when the filename is retrieved programmatically e.g.
elsewhere in a script
Also various comments refer to using single quotation marks around
strings to
stop powershell interpreting wildcard characters.
I have been unable to get this working, specifically when using the
get-item or get-acl commands
(PERHAPS someone can me an example to try on my machine)
Even if I could get it working I again see potential problems when the
filename string is retrieved programmatically.
(PERHAPS again someone can me an example to try on my machine)
Another suggestion which I have read is to use the parameter
-LiteralPath
This is suggested when using get-childitem.
This parameter is not an option on my Powershell and neither is it an
option for get-item and get-acl.
AM I on the right version of Powershell? I have version 1.0.9567.0
according to Add-Remove Programs.
In frustration I have been performing tests and think I have cracked
it.
Trying to explain what I have found is not easy but I have tried my
best!
The following text takes you step-by-step through what I did and what I
found.
I think this is the clearest way I can come up with.
Create a folder with one file in called test[1].txt
From that folder enter the following command:
$a=(get-item *).name
This sets $a to be the string test[1].txt
Enter the following command:
get-acl *
This returns the following error:
Cannot find path 'test[1].sfx' because it does not exist.
The command is interpreting the [] as wildcards - see Follow up
exercise below (at end)
Now enter the following command:
get-acl $a
This produces no output as it is interpreting the [] in $a as wildcards
and hence
the command is actually looking for a file named test1.txt - see Follow
up exercise below (at end)
To get the required results the [ and ] characters in the name returned
by
get-item need escaping to stop them being interpreted as wildcards.
This can be done by using the string method .replace to insert escape
characters i.e.`
You might think the form would be .replace("[","`[") except this will
not work
In the first instance, powershell checks for wildcards in the first
parameter of the replace so
the first [ in this command is interpreted as a wildcard - which is
meaningless as there is no ] to pair with it
The form .replace("`[","`[") is correct in the first parameter i.e. it
will search for instances of [ but
the form fails because the `[ in the second parameter is interpreted as
an escaped [ so the replacement string is
simply [ i.e. this form replaces [ with [ - nothing changes
NOTE the second parameter does not interpret [ or ] as a wildcard so
using a single ` is
no different to having no ` at all
The form .replace("`[","``[") works because the double backtick `` in
the second parameter is treated as
an escaped backtick and the [ is not treated as a wildcard in the
second parameter so
the resultant replacement string is `[
So to replace all instances of [ or ] with `[ or `] the complete form
is:
.replace("`[","``[").replace("`]","``]")
So for the get-acl command above the correct form is:
get-acl ((get-item *).name.replace("`[","``[").replace("`]","``]"))
Also....
The following form does not work - haven't got my head round why:
get-acl ((get-item
*).name.replace("`[","````[").replace("`]","````]"))
and the following form does work - but again I haven't got my head
round why:
get-acl ((get-item
*).name.replace("`[","``````[").replace("`]","``````]"))
There must be a better way than this....
Again any example of how to do all this using snigle quotation marks
would be
appreciated - particularly when done inside a script or over two
command line entries
e.g. a working example of the following (where again the get-acl
command produces no output)
$a='test[1].txt'
get-acl $a
Follow up exercise
Create a file called test1.txt in the test folder
i.e. the folder now contains test[1].txt and test1.txt
From the folder run the following command:
get-item *
The output produced shows 2 entries as expected:
Name
----
test1.txt
test[1].txt
Now enter the following command:
get-acl *
The output produced shows 2 entries which are not as expected:
Path
----
test1.txt
test1.txt
The get-acl command is interpreting the wildcards in the strings
returned from the expansion of
the * wildcard.
Further investigations (by tweeking permissions) show that get-acl is
returning 2 instances of
the exact same file object.
understand
the need for using escape characters when referring to such files but
the comments I have found always assume the string for the file name
is
entered manually.
This is no use when the filename is retrieved programmatically e.g.
elsewhere in a script
Also various comments refer to using single quotation marks around
strings to
stop powershell interpreting wildcard characters.
I have been unable to get this working, specifically when using the
get-item or get-acl commands
(PERHAPS someone can me an example to try on my machine)
Even if I could get it working I again see potential problems when the
filename string is retrieved programmatically.
(PERHAPS again someone can me an example to try on my machine)
Another suggestion which I have read is to use the parameter
-LiteralPath
This is suggested when using get-childitem.
This parameter is not an option on my Powershell and neither is it an
option for get-item and get-acl.
AM I on the right version of Powershell? I have version 1.0.9567.0
according to Add-Remove Programs.
In frustration I have been performing tests and think I have cracked
it.
Trying to explain what I have found is not easy but I have tried my
best!
The following text takes you step-by-step through what I did and what I
found.
I think this is the clearest way I can come up with.
Create a folder with one file in called test[1].txt
From that folder enter the following command:
$a=(get-item *).name
This sets $a to be the string test[1].txt
Enter the following command:
get-acl *
This returns the following error:
Cannot find path 'test[1].sfx' because it does not exist.
The command is interpreting the [] as wildcards - see Follow up
exercise below (at end)
Now enter the following command:
get-acl $a
This produces no output as it is interpreting the [] in $a as wildcards
and hence
the command is actually looking for a file named test1.txt - see Follow
up exercise below (at end)
To get the required results the [ and ] characters in the name returned
by
get-item need escaping to stop them being interpreted as wildcards.
This can be done by using the string method .replace to insert escape
characters i.e.`
You might think the form would be .replace("[","`[") except this will
not work
In the first instance, powershell checks for wildcards in the first
parameter of the replace so
the first [ in this command is interpreted as a wildcard - which is
meaningless as there is no ] to pair with it
The form .replace("`[","`[") is correct in the first parameter i.e. it
will search for instances of [ but
the form fails because the `[ in the second parameter is interpreted as
an escaped [ so the replacement string is
simply [ i.e. this form replaces [ with [ - nothing changes
NOTE the second parameter does not interpret [ or ] as a wildcard so
using a single ` is
no different to having no ` at all
The form .replace("`[","``[") works because the double backtick `` in
the second parameter is treated as
an escaped backtick and the [ is not treated as a wildcard in the
second parameter so
the resultant replacement string is `[
So to replace all instances of [ or ] with `[ or `] the complete form
is:
.replace("`[","``[").replace("`]","``]")
So for the get-acl command above the correct form is:
get-acl ((get-item *).name.replace("`[","``[").replace("`]","``]"))
Also....
The following form does not work - haven't got my head round why:
get-acl ((get-item
*).name.replace("`[","````[").replace("`]","````]"))
and the following form does work - but again I haven't got my head
round why:
get-acl ((get-item
*).name.replace("`[","``````[").replace("`]","``````]"))
There must be a better way than this....
Again any example of how to do all this using snigle quotation marks
would be
appreciated - particularly when done inside a script or over two
command line entries
e.g. a working example of the following (where again the get-acl
command produces no output)
$a='test[1].txt'
get-acl $a
Follow up exercise
Create a file called test1.txt in the test folder
i.e. the folder now contains test[1].txt and test1.txt
From the folder run the following command:
get-item *
The output produced shows 2 entries as expected:
Name
----
test1.txt
test[1].txt
Now enter the following command:
get-acl *
The output produced shows 2 entries which are not as expected:
Path
----
test1.txt
test1.txt
The get-acl command is interpreting the wildcards in the strings
returned from the expansion of
the * wildcard.
Further investigations (by tweeking permissions) show that get-acl is
returning 2 instances of
the exact same file object.
--
Whisperer
Whisperer