gpt4 book ai didi

windows - 如何从Windows批处理脚本中的文件路径获取父目录名称?

转载 作者:行者123 更新时间:2023-12-03 11:12:13 25 4
gpt4 key购买 nike

我有一个根文件夹C:\EncryptedFiles。可能有多个子文件夹。每个子文件夹最多可以有一个文件。无法事先知道会有多少个子文件夹。我需要遍历每个文件,对其进行解密,然后将解密后的文件输出到单独的文件夹中,该文件的名称应与命名约定 ParentDirectoryOfFile_YYYYMMDD 匹配。

最初,我一直在努力进行循环以解密,但是在this帖子中对此进行了回答:

set "ROOTDIR=C:\EncryptedFiles"
for /R %ROOTDIR% %%i in (*.gpg) do (
gpg --batch --yes --passphrase mypassword --output "%%~dpni" --decrypt "%%~i"
)

在上面的代码中, --output "%%~dpni"将输出文件(其名称与输入文件相同,但没有扩展名 .gpg)放在同一文件夹中。但是我希望所有解密文件都以 ParentDirectoryOfFile_YYYYMMDD 的命名约定存储在 C:\DecryptedFiles中。

例如,我具有以下目录结构:
C:\EncryptedFiles
\Folder1
File1.csv.gpg
\Folder2
File2.csv.gpg

当前代码将产生最终输出,如下所示:
C:\EncryptedFiles
\Folder1
File1.csv.gpg
File1.csv
\Folder2
File2.csv.gpg
File2.csv

因此,它将解密文件准确地放置在各个加密文件所在的位置。但是,我想要的是所有解密的文件都进入一个单独的文件夹(并保留 C:\EncryptedFiles文件夹结构不变)。我希望输出是这样的:
C:\DecryptedFiles
Folder1_20191119.csv
Folder2_20191119.csv

我知道需求听起来可能很愚蠢,但这就是事实。加密文件的原始名称在这里没有意义。它们最初放置在哪个文件夹中可以识别它们。

所以这是我到目前为止尝试过的:
set "ROOTDIR=C:\EncryptedFiles"
set "DESTINATIONDIR=C:\DecryptedFiles"
for /R %ROOTDIR% %%i in (*.gpg) do (
gpg --batch --yes --passphrase mypassword --output "%DESTINATIONDIR%\%%~ni_%date:~10,4%%date:~7,2%%date:~4,2%" --decrypt "%%~i"
)

上面的代码的问题是 %%~ni提供了原始文件名,因此我得到以下输出:
C:\DecryptedFiles
File1.csv_20191119.csv
File2.csv_20191119.csv

我希望显示其父目录名称,而不是 File1.csvFile2.csv部分。

我知道 %%i包含加密文件的完整路径名。我应该能够以某种方式提取直接父目录的名称。这里有一些很好的讨论: https://www.dostips.com/forum/viewtopic.php?t=2427,但是当我尝试时,父目录原来是空白的。

最佳答案

我建议按照此批处理代码而不是来执行此任务,而不是真正不需要使用delayed expansion,因此,对于名称或路径包含一个或多个感叹号的文件,也应使用该批处理代码。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "RootDirectory=C:\EncryptedFiles"
set "DestinationDirectory=C:\DecryptedFiles"

if not exist "%DestinationDirectory%\" md "%DestinationDirectory%"
if not exist "%DestinationDirectory%\" (
echo ERROR: Failed to create directory: "%DestinationDirectory%"
echo/
pause
goto EndBatch
)

rem Get current date in format yyyyMMdd region independent.
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "FileNameDate=%%I"
set "FileNameDate=%FileNameDate:~0,8%"

for /R "%RootDirectory%" %%I in (*.csv.gpg) do for %%J in ("%%~dpI.") do gpg.exe --batch --yes --passphrase mypassword --output "%DestinationDirectory%\%%~nxJ_%FileNameDate%.csv" --decrypt "%%I"

:EndBatch
endlocal
请阅读我对 Why does %date% produce a different result in batch file executed as scheduled task?的回答。它非常详细地解释了两个命令行,以独立于 yyyyMMdd 区域的格式获取当前日期。
对于通配符模式 *.csv.gpg在指定的根目录或其子目录之一中找到的每个非隐藏文件, 一个更多 FOR 用于通过引用始终以文件结尾的完整路径来仅获取包含此文件的文件夹的名称。加上反斜杠并附加一个点以引用目录本身。请参阅Microsoft文档页面 Naming Files, Paths, and Namespaces
内部 FOR 确定包含该文件的文件夹的全限定名称,该文件为 %%~dpI,末尾没有反斜杠。 %%~nxJ引用最后一个反斜杠之后的字符串,该字符串是包含当前加密文件的无路径文件夹的全名。如果可以保证没有文件夹包含不寻常的 %%~nJ名称,但是也可以使用 .来引用文件夹名称。
为了了解所使用的命令及其工作方式,请打开 command prompt窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • md /?
  • pause /?
  • rem /?
  • set /?
  • setlocal /?
  • wmic /?
  • wmic os /?
  • wmic os get /?
  • wmic os get localdatetime /?
  • 关于windows - 如何从Windows批处理脚本中的文件路径获取父目录名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58945785/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com