我处理过数十万个文件夹/文件,其中大多数都有特定的日志文件。手动浏览文件夹来抓取日志需要花费很多时间,所以我一直使用脚本来完成这项工作。
它是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我需要有索引跳过任何目录中包含“共同”或“旧”的词,以及其他潜在的。这样做的目的是通过根本不进入这些目录来节省时间。
我尝试过调查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谢谢!
发布于 2014-04-07 13:19:21
@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时跳过这些行。
在输入这个的过程中,我意识到还有一个小小的简化……不过,我得等着喝早茶。
@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内容进行重新过滤是多余的-删除这一点意味着,为克服笨拙字符而建立的引用机制可能会缩减规模。然后在现实中,原始文件是原始添加(临时文件)到一个空的临时文件,所以-稍微重组和挥手(因为'skip=0‘是无效的),结果是后来扫描的唯一目录是在最后一次迭代中添加的目录,优化了目录扫描方法。
现在,结果列表将是\a\、\b\、\c\、\a\a1\、\b\b1\,依此类推-但如果需要,结果的一个简单sort就可以处理这些内容。
发布于 2014-04-09 09:58:57
这可能会有所帮助:它排除了您看到"Common Old"的第3行中的术语
它创建一个文件夹列表,过滤掉排除的术语,并使用剩余的文件夹创建该列表。
如果只需要*.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
)https://stackoverflow.com/questions/22903564
复制相似问题