運行Windows 7,當我例行文件備份在文件複製到外部硬盤,我使用PowerShell V2(從批處理文件運行)對拷貝重新創建文件中的所有時間戳的原始文件。批處理文件中的Powershell - 如何轉義元字符?
下面的代碼工作成功地在大多數情況下,但並非總是如此: -
SET file=%1
SET dest=E:\
COPY /V /Y %file% "%dest%"
SetLocal EnableDelayedExpansion
FOR /F "usebackq delims==" %%A IN ('%file%') DO (
SET fpath=%%~dpA
SET fname=%%~nxA
)
PowerShell.exe (Get-Item \"%dest%\%fname%\").CreationTime=$(Get-Item \"%fpath%%fname%\" ^| Select-Object -ExpandProperty CreationTime ^| Get-Date -f \"MM-dd-yyyy HH:mm:ss\")
上面的代碼複製該文件,然後設置創建日期/時間上的副本(目標)文件到的源文件,當我拖放源文件到我的批處理文件。
但在某些情況下,代碼失敗。如果文件名包含'毒'字符,如(例如)方括號 [...],則會給出錯誤「屬性'CreationTime'在此對象上找不到」。解析文件名顯然在'毒'字上失敗。
的代碼做不得到具有符號如&錯誤。
我已經嘗試了使用單引號和雙引號轉義Powershell命令的全部變體,但沒有成功。請有人能告訴我如何逃避那些Powershell對象的角色。
這只是一個很長的批處理例程的一小部分,我依賴這個例程進行常規系統備份。我沒有選擇切換到.ps1文件,所以我需要一個在批處理文件中工作的解決方案,而不是在.ps1文件中。
感謝您的所有建議。
附錄:我找到了一個解決方案,採用了一個由mklement0提供的建議。我用方括號問題:在對我原來的PowerShell命令替換以下命令克服 -
PowerShell.exe (Get-Item -LiteralPath \"%dest%\%fname%\").CreationTime=$(Get-Item -LiteralPath \"%fpath%%fname%\" ^| Select-Object -ExpandProperty CreationTime ^| Get-Date -f \"MM-dd-yyyy HH:mm:ss\")
以供將來參考,請注意(在Windows 7的):
採用這個修改後的命令可以成功保留任何額外的空格字符。它是而不是必須包含一對額外的雙引號字符才能實現。
- 編者按:這是一個邊緣的情況下,但值得指出的是:不需要額外的封閉雙引號的不止一個空間任何運行被摺疊成一個空間;例如,
powershell.exe -command echo \"a b\"
收益率a b
。
括在"..."
整個命令有助於原則 -
powershell.exe -command "echo \"a b\""
- 但由於cmd.exe
然後不承認整個字符串作爲單,雙引號字符串,元字符可以突破的命令;例如,
powershell.exe -command "echo \"a & b\""
- 編者按:這是一個邊緣的情況下,但值得指出的是:不需要額外的封閉雙引號的不止一個空間任何運行被摺疊成一個空間;例如,
這是不可能的文件路徑包括任何「(雙引號)字符,所以沒有代碼需要轉義字符,雙引號字符是非法的字符在FAT和NTFS文件系統中,因此永遠不會遇到文件的路徑
在Powershell命令中使用'(單引號)是不好的,因爲該字符在NTFS文件中不是非法的系統,因此可以在文件的實際路徑中找到。必須使用雙引號紅色,因爲雙引號字符是非法的,在實際的NTFS路徑中永遠不會遇到。
隨着ROBOCOPY,下列通配符解決方案成功甚至用最毒的字符 - 除!(即,它可以應對= &「^)。這個命令是相當強勁,即使有更比一個毒字(但並非萬無一失):
ROBOCOPY "%fpath% " "%dest%" "*%name%*%ext%*" /B /COPY:DAT /XJ /SL /R:0 /W:0 /V
一個。 「%fpath%」中的空格是ESSENTIAL,它不是錯誤。
b。在所有情況下致命的唯一毒藥字符是EXCLAMATION MARK(!)。
c。有毒字符只在FILENAME中出現問題,而不在路徑中。
良好的漁獲後重新在'「%路徑%‘'空間:問題是,'robocopy'’在一個參數作爲_escaped_'的端'」',打破了命令對待一個'\ 。嚴格地說,正確的解決方法是_double_尾部的'\'(例如''E:\\「'),但是您可以附加一個_space_,因爲路徑中任何尾隨的空白都是_ignored_。因此,使這種調用健壯的一種簡單方法是在傳遞文件夾路徑時,_always_使用'「%var%」'(在結束雙引號之前的尾部空格)。我相應地更新了我的答案。 – mklement0
只有_filenames_易受wildard元字符解釋影響:確實:'robocopy'只支持'file'(_filename_)參數中的通配符,而不支持'source'和'destination'(_folder_)參數中的通配符;文件夾路徑始終被視爲文字。 – mklement0
專業術語:請打電話給「posion characters」(通配符)_metacharacters_,這是已建立的和apt-term。 '!'只有問題,因爲你正在使用'enabledelayedexpansion' - 沒有它,'!'將被視爲文字。還有哪些元字符有問題? – mklement0