好的,所以我一直在这里贴墙(嘿嘿)。 我正在寻找一个选项/代码,允许我从.bat脚本中搜索部分路径和/或文件名,我将导出到外部文件。
现在,“搜索”,“导出”和“外部文件”是我很好的选择。令我头疼的部分是“部分”。
详细说明。 我正在寻找一个名为DATA的文件夹和一个名为userinfo.txt的文件。 那些是不变的。所以我的路径是DATA \ userinfo.txt 我也99%肯定这个文件夹将在D:\中,但这不是现在关注的问题。我会在哪里找到它。 但我无法弄清楚如何为我的生活寻找一个部分路径\文件名。
我已经指定DATA \ userinfo.txt是常量的原因是由于其他文件夹能够被任意命名。因此,在我的下面示例中,01-12-2016不必根据该约定命名。对于美国来说,它最有可能被命名为12-01-2016。它有时也被命名为20161201或20160112,或者最重要的是具有字母前缀,例如d01-12-2016。在那个音符上DATA总是DATA,这就是为什么我说DATA在我的搜索中是不变的。另外一件事是祖父母文件夹。当我说“相同”时,我指的是两个应用程序之间的“共享”。这并不意味着它总是被命名为“程序”,如下例所示。
谷歌搜索并使用我所知道的东西让我无处可去。
原因我不能简单地使用
where /r d: userinfo.txt
是该特定命令将返回数百个结果,因为为程序运行的每个.single.day创建了userinfo.txt并单独存储。
另外 - 如果有方法可以梳理数百个结果并找到匹配的部分来解决我的问题。
然而这引起了另一个令人头疼的问题,因为通常有多个程序使用这个确切的文件。
所以在
的例子中d:\users\path\program\storage\01-12-2016\userinfo.txt
d:\users\path\program\otherstorage\01-12-2016\userinfo.txt
d:\users\path\program\storage\02-12-2016\userinfo.txt
d:\users\path\program\otherstorage\02-12-2016\userinfo.txt
d:\users\path\program\storage\03-12-2016\userinfo.txt
d:\users\path\program\otherstorage\03-12-2016\userinfo.txt
d:\users\path\program\storage\04-12-2016\userinfo.txt
d:\users\path\program\otherstorage\04-12-2016\userinfo.txt
d:\users\path\program\storage\05-12-2016\userinfo.txt
d:\users\path\program\otherstorage\05-12-2016\userinfo.txt
d:\users\path\program\storage\06-12-2016\userinfo.txt
d:\users\path\program\otherstorage\06-12-2016\userinfo.txt
d:\users\path\program\storage\data\userinfo.txt
d:\users\path\program\otherstorage\data\userinfo.txt
注意:存储,otherstorage,storageother,storage2,storagegh都是任意名称,因为这些文件夹的命名符合最终用户的意愿。 我想为
导出两个单独的变量d:\users\path\program\storage
和
d:\users\path\program\otherstorage
我还需要为\ data \ userinfo.txt
执行此操作因此,如果搜索\ data \ userinfo.txt,它将返回
d:\users\path\program\storage\data\userinfo.txt
d:\users\path\program\otherstorage\data\userinfo.txt
我也想隔离两个
d:\users\path\program\storage
和
d:\users\path\program\otherstorage
并将其用作(单独的)局部变量。
我需要注意的是,安装/下载任何外部脚本工具/辅助工具都不适合我在很多计/或外部下载/安装的足够权限,因此任何未集成到球棒中并且需要单独导入的内容都是一个坏主意。
此外,我正在使用Windows XP SP3,但我需要这款游戏能够在XP SP2,XP SP3,Windows 7,Windows 10,Windows NT,Windows 2000上运行。
任何帮助都将不胜感激。
请注意
d:\users\path\program
也是一个可接受的变量。在这种情况下,我会手动修改路径的其余部分,或者依赖最终用户(我的同事)输入来正确完成路径。最后证明是愚蠢的差事。
到目前为止,我一直在处理的方法是查找我知道将在两个文件夹中的.exe。这是我编写的代码的一部分,以匹配当前示例。
@echo off
SETLOCAL
echo Program will now look for program.exe and programgh.exe. Please input, when asked, matching part of the path for these files.
echo Example:
echo d:\users\path\program\storage\bin\program.exe
echo d:\users\path\program\otherstorage\bin\programgh.exe
echo In above example matching part is d:\users\path\program so you would enter that when prompted
echo Please do not input the last pathing mark: \ (backslash)
echo -------------searching---------------
::I am exporting errors to nul as I don't want them to be spammed by errors and other data that they would think is their fault
where /r c: program*.exe 2>nul
where /r d: program*.exe 2>nul
where /r e: program*.exe 2>nul
where /r f: program*.exe 2>nul
set /p dualpath="Please enter matching paths for program folder: "
之后我将继续使用%dualpath%变量。
正如通常发生的那样(至少对我而言),大多数人只是复制示例路径而不看看程序吐出的内容,并且会混淆程序无法运行的原因。或者将所有内容复制到program.exe和programgh.exe - 包括otherstorage \ bin \,而不会注意到\ storage \和\ otherstorage \不匹配。
我认为这现在涵盖了所有评论或其他问题,并且更清楚地说明了我需要的内容。感谢大家的帮助,我希望这更容易理解。
答案 0 :(得分:1)
如果Windows cmd
命令允许(partially or fully qualified) path中的通配符,则必须仅在path leaf(即路径中的最后一个项目或容器)中使用通配符。但是,您可以应用findstr
regex来缩小命令输出,例如如下:
where /r d:\ userinfo.txt | findstr /I "\\storage2*\\data\\userinfo.txt"
以上命令将输出缩小到路径结尾 \storage\data\userinfo.txt
和\storage2\data\userinfo.txt
另一个示例 - 使用\storageX\data\userinfo.txt
将输出缩小到路径结尾,其中X
无任何或任何十进制密码[0-9]
:
dir /B /S d:\userinfo.txt | findstr /I "\\storage[0-9]*\\data\\userinfo.txt"
将路径放入环境变量(使用_var
前缀以便于下一次识别),例如_varstorage
,_varstorage2
,...
@ECHO OFF
SETLOCAL EnableExtensions
for /F "delims=" %%F in ('
dir /B /S "d:\userinfo.txt" ^| findstr /I "\\storage[0-9]*\\data\\userinfo.txt"') do (
for /D %%D in ("%%~dpF..") do (
set "_var%%~nxD=%%~fD"
rem %%~fD path
rem %%~nxD last item in above path
rem _var variable name prefix
)
)
rem show result:
set _var
另请参阅下一个%%~nxD
和%%~D
说明:Command Line arguments (Parameters): Parameter Extensions
答案 1 :(得分:0)
基于您的上述样本
@Echo off
Set Search=\\data\\userinfo.txt
pushd "D:\Users\path\program
For /f "Delims=" %%A in (
'Dir /B/S/A-D userinfo.txt ^|findstr "%Search%$"'
) Do Call :Sub "%%~fA" "%%~dpA.."
Popd
Goto :Eof
:Sub FullName DrivePath
Echo Found %~nx1
Echo in %~dp1
Echo Granny %~nx2
Set "Granny=%~nx2"
Echo in %~dp2
Echo -------
应该提供此输出(仅部分测试)
Found userinfo.txt
in D:\Users\path\program\storage\data\
Granny storage
in D:\Users\path\program\
-------
Found userinfo.txt
in D:\Users\path\program\storage2\data\
Granny storage2
in D:\Users\path\program\
-------
Search
中的反斜杠必须加倍,因为它是findstr的转义字符
答案 2 :(得分:0)
如果我的意图正确,下面的脚本应该按照你想要的那样做:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_ROOT=D:\" & rem "D:\", "D:\users",..., or "D:\users\path\program"
set "_FILE=userinfo.txt"
rem // Initialise index:
set /A "INDEX=1"
rem // Search for the specified file in the given root directory:
for /F "delims=" %%F in ('dir /B /S "%_ROOT%\%_FILE%"') do (
rem // Iterate once over the grandparent directory itself:
for /D %%D in ("%%F\..\..") do (
rem // Resolve the path of the grantparent directory;
set "ITEM=%%~fD"
rem // Initialise flag (non-empty means not yet stored):
set "FLAG=#"
rem // Toggle delayed expansion to avoid trouble with exclamation marks:
setlocal EnableDelayedExpansion
rem // Iterate over all currently stored grantparent paths:
for /F "tokens=1,* delims==" %%V in ('2^> nul set $ARRAY[') do (
rem // Clear flag in case current grandparent has already been stored:
if /I "!%%V!"=="!ITEM!" set "FLAG="
)
rem // Check flag:
if defined FLAG (
rem // Flag is empty, so current grandparent needs to be stored:
set "$ARRAY[!INDEX!]=!ITEM!"
rem // Transfer stored grandparent over localisation barrier:
for /F "delims=" %%E in ("$ARRAY[!INDEX!]=!ITEM!") do (
endlocal
set "%%E"
)
rem // Increment index
set /A "INDEX+=1"
) else endlocal
)
)
rem // Retrieving final count of grandparent directories:
set /A "INDEX-=1"
rem // Return stored grandparent paths:
set $ARRAY[
endlocal
exit /B
这会在您的情况下返回D:\users\path\programs\otherstorage
和D:\users\path\programs\storage
,它们分别存储在变量$ARRAY[1]
和$ARRAY[2]
中。由于数组样式变量,这种方法足够灵活,可以涵盖存在两个以上祖父目录的情况。