我使用数十万个文件夹/文件,其中大多数都有某些日志文件。手动浏览文件夹以获取日志需要花费大量时间,因此我一直在使用脚本来执行此操作。
它是一个2人。第一部分在一夜之间运行以解析所有目录(它们每天都会更改,并且会经常添加新日志,因此我会每晚对所有内容进行索引以使索引保持最新状态。)
这第一部分是自动的,我从不触摸它,它只是每晚运行。输出转到txt文件,在执行第二个脚本时使用。
我在第二个脚本中放入了我正在寻找的日志的关键字。此脚本依赖于第一个脚本的txt输出来快速定位文件并将其下拉。
(我这样做的原因是因为它有5秒的任务来解析寻找文件的300,000行文本文件,以及15-30分钟的搜索工作(索引所有网络共享)。我可以在5秒钟而不是30多分钟内获取我的日志。
在上周之前,日志目录包含大约5000个文件和文件夹。上周末,IT切换到了一个新系统,它现在包含超过500,000个文件和文件夹。他们抛弃了档案,还有一堆我不需要的其他档案。
用于在大约10-15分钟内对其进行索引的第一个脚本(它的网络共享,实际上是4个网络共享),一夜之间没问题。虽然现在这是一个4小时以上的壮举。我需要能够在索引编制期间排除某些目录,从而将500,000个文件/文件夹数量减少到5,000以下。
我一直用这个命令来索引:
dir /b /-d /-p /s /A:-D > C:\output.txt
我需要让索引跳过包含单词“Common”或“Old”的任何目录,也可能跳过其他目录。目标是通过不进入这些目录来节省时间。
我尝试使用PowerShell来做这件事,但我对此一无所知。
我需要输出格式如下:
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\dbInstaller.exe
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\DisplayDriver.nvi
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\DisplayDriverExt.dll
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\license.txt
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\mcu.ex_
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\nvae.inf
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\nvak.inf
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\nvapi.dl_
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\nvapi64.dl_
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\nvcompiler.dl_
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\nvcompiler32.dl_
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\nvcplsetupeng.exe
谢谢!
答案 0 :(得分:0)
@ECHO OFF
SETLOCAL
SET "sourcedir=."
(
FOR /f "delims=" %%a IN (
'dir /b /s /ad "%sourcedir%\*" ^|findstr /v /i /l /g:q22903564.txt'
) DO ( FOR /f "delims=" %%b IN ('dir /b /a-d "%%a" 2^>nul') DO ECHO(%%a\%%b
)
)>newfile.txt
GOTO :EOF
我使用了一个名为q22903564.txt
的文件,其中包含用于测试的排除字词。
生成newfile.txt。
当然,sourcedir
,q22903564.txt
和newfile.txt
的选择都在你的法庭上......
@ECHO OFF
SETLOCAL
:: make a tempfile
:maketemp
SET "tempfile=%temp%\%random%"
IF EXIST "%tempfile%*" (GOTO maketemp) ELSE (ECHO.>"%tempfile%a")
SET "sourcedir=."
:: get a dir listing from the root
(
FOR /f "delims=" %%a IN (
'dir /b /ad "%sourcedir%\*" ^|findstr /v /i /l /g:q22903564.txt'
) DO (ECHO("%%~fa")
)>"%tempfile%b"
:again
(
FOR /f "usebackqdelims=" %%a IN ("%tempfile%b") DO (
FOR /f "delims=" %%b IN (
'dir /b /ad "%%~a\*" ^|findstr /v /i /l /g:q22903564.txt'
) DO FOR /f "delims=" %%c IN ('ECHO("%%~a\%%b"^|findstr /x /v /i /l /g:"%tempfile%b"') DO ECHO "%%~c"
)
)>"%tempfile%c"
FOR %%a IN ("%tempfile%c") DO SET /a sizec=%%~za
IF %sizec% gtr 0 TYPE "%tempfile%c">>"%tempfile%b"&GOTO again
(
FOR /f "usebackqdelims=" %%a IN ("%tempfile%b") DO (
FOR /f "delims=" %%b IN (
'dir /b /a-d "%%~a\*" 2^>nul'
) DO ECHO(%%~a\%%b
)
)>newfile.txt
DEL "%tempfile%*"
GOTO :eof
嗯 - 需要向你收取额外的费用,据一些人说,这是不可能的。
@ECHO OFF
SETLOCAL
:: make a tempfile
:maketemp
SET "tempfile=%temp%\%random%"
IF EXIST "%tempfile%*" (GOTO maketemp) ELSE (ECHO.>"%tempfile%a")
SET "sourcedir=."
:: get a dir listing from the root
(
FOR /f "delims=" %%a IN (
'dir /b /ad "%sourcedir%\*" ^|findstr /v /i /l /g:q22903564.txt'
) DO (ECHO("%%~fa")
)>"%tempfile%b"
SET /a sizec=0
:again
SET "skipcnt=usebackq"
IF %sizec% gtr 0 (
FOR /f %%a IN ('type "%tempfile%b" ^|find /c /v ""') DO SET "skipcnt=usebackqskip=%%a"
TYPE "%tempfile%c">>"%tempfile%b"
)
(
FOR /f "%skipcnt%delims=" %%a IN ("%tempfile%b") DO (
FOR /f "delims=" %%b IN (
'dir /b /ad "%%~a\*" ^|findstr /v /i /l /g:q22903564.txt'
) DO FOR /f "delims=" %%c IN ('ECHO("%%~a\%%b"^|findstr /x /v /i /l /g:"%tempfile%b"') DO ECHO "%%~c"
)
)>"%tempfile%c"
FOR %%a IN ("%tempfile%c") DO SET /a sizec=%%~za
IF %sizec% gtr 0 GOTO again
(
FOR /f "usebackqdelims=" %%a IN ("%tempfile%b") DO (
FOR /f "delims=" %%b IN (
'dir /b /a-d "%%~a\*" 2^>nul'
) DO ECHO(%%~a\%%b
)
)>newfile.txt
DEL "%tempfile%*"
GOTO :eof
第三次是魅力。此版本计算出已经处理了多少行目录,并在重新处理连接列表b和c时跳过这些行。 IOW,它只处理添加内容。
在打字时,我意识到还有一点简化......不得不等早茶......不过......
@ECHO OFF
SETLOCAL
:: make a tempfile
:maketemp
SET "tempfile=%temp%\%random%"
IF EXIST "%tempfile%*" (GOTO maketemp) ELSE (ECHO.>"%tempfile%a")
SET "sourcedir=."
:: get a dir listing from the root
(
FOR /f "delims=" %%a IN (
'dir /b /ad "%sourcedir%\*" ^|findstr /v /i /l /g:q22903564.txt'
) DO ECHO(%%~fa
)>"%tempfile%c"
SET /a sizec=0
:again
SET "skipcnt=usebackq"
IF %sizec% neq 0 FOR /f %%a IN ('type "%tempfile%b" ^|find /c /v ""') DO SET "skipcnt=usebackqskip=%%a"
TYPE "%tempfile%c">>"%tempfile%b"
(
FOR /f "%skipcnt%delims=" %%a IN ("%tempfile%b") DO (
FOR /f "delims=" %%b IN (
'dir /b /ad "%%a\*" ^|findstr /v /i /l /g:q22903564.txt'
) DO ECHO(%%a\%%b
)
)>"%tempfile%c"
FOR %%a IN ("%tempfile%c") DO SET /a sizec=%%~za
IF %sizec% gtr 0 GOTO again
(
FOR /f "usebackqdelims=" %%a IN ("%tempfile%b") DO (
FOR /f "delims=" %%b IN (
'dir /b /a-d "%%a\*" 2^>nul'
) DO ECHO(%%a\%%b
)
)>newfile.txt
DEL "%tempfile%*"
GOTO :EOF
这次肯定! (没有狮子的吼声)
我意识到对原始tempfileb内容的重新过滤是多余的 - 并且删除这意味着可以缩减用于克服尴尬角色的引用制度。然后实际上原始文件是一个空的tempfileb的原始添加(tempfilec),所以 - 一点重组和挥手(因为'skip = 0'无效),结果是以后扫描的唯一目录是在最后一次迭代中添加了thos,优化了目录扫描方法。
现在结果是结果列表将是\ a \,\ b \,\ c \,\ a \ a1 \,\ b \ b1 \等等 - 但是简单的sort
如果需要,结果应该照顾好。
答案 1 :(得分:0)
这可能有所帮助:它会排除第3行中您看到"Common Old"
它会创建文件夹列表,过滤掉排除的字词,然后使用剩余的文件夹创建列表。
如果您只想要*.log *.txt
个文件等,那么可以再次提高效率 - 否则请删除第7行批处理文件中的*.log *.txt
条款
@echo off
dir /b /ad /s /-p > "C:\output.txt"
findstr /v /i "Common Old" "C:\output.txt" >"C:\output2.txt"
del "C:\output.txt"
for /f "usebackq delims=" %%a in ("C:\output2.txt") do (
pushd "%%a"
for /f "delims=" %%b in ('dir *.log *.txt /b /-p /a-d') do >>"C:\output.txt" echo(%%a\%%b
popd
)