Aci*_*cid 2 windows for-loop batch-file
将我的脚本分成两个批处理文件,因为我不知道如何组合它:
很短,这样你就明白了:
1.bat:使用参数调用 2.bat,对其输出进行排序并使行唯一
FOR /F ... (2.bat %1 ^| sort) DO (...)
Run Code Online (Sandbox Code Playgroud)
do 部分将行相互比较并使用行缓冲区排除相同的行
2.bat:打印 FOR 循环的结果字符串
FOR ... DO ECHO
Run Code Online (Sandbox Code Playgroud)
在 bash 中,这可能看起来像这样:(管道很容易)
(command) | while read line ; do echo $line ; done | sort | uniq
Run Code Online (Sandbox Code Playgroud)
我真的不知道如何在 Windows 批处理中处理 FOR 循环的最终输出,以将其结果与另一个循环一起使用(不使用临时文件进行结果缓冲)
这是应用 jeb 解决方案的完整代码:
@echo off
setlocal EnableDelayedExpansion
REM *** This "goto" to a label, if there is one embedded in %~0 -
FOR /F "delims=: tokens=3" %%L in ("%~0") do goto :%%L
REM *** The second part calls this batch file, but embedd a label to be called
FOR /F "usebackq" %%A IN (`echo dummy ^| call %~d0\:main:\..\%~pnx0 %1 ^| SORT`) DO (
IF NOT "%%A"=="!buff!" SET str=!str!%%A
SET buff=%%A
)
ECHO %str:.dll=;%
endlocal
GOTO :eof
REM *** This function will be called in the pipe, but runs in batch context
:main
CD %1
:sub
FOR %%A IN (*.dll *.exe) DO dumpbin /DEPENDENTS %%A | FINDSTR /I "DLL" | FINDSTR /V "Dump :"
FOR /D %%B IN (*) DO (
CD %%B
CALL :sub
CD..
)
GOTO :eof
Run Code Online (Sandbox Code Playgroud)
它返回一行,其中包含文件夹[arg1] 及其所有子文件夹内所有文件的运行时依赖关系:输出字符串的 .dll 部分被删除以满足我的需要
ADVAPI32;COMCTL32;COMDLG32;GDI32;KERNEL32;ole32;SHELL32;USER32;WININET;
这是 osx 上使用 pev 工具的对应内容:
#!/bin/sh
find "${1}" -type f \( -iname "*.dll" -o -iname "*.exe" \) | while read pe ; do
readpe -i "${pe}" | grep -i '.dll' | awk '{print $2}'
done | sort | uniq | sed 's/.[dD][lL][lL]//g;' | tr '\n' ';' ## have the BSD sed release and can't use I with sed
Run Code Online (Sandbox Code Playgroud)
第一步很简单
command | (
for /f "delims=" %%L in ('more') DO @(
echo # %%L
)
) | sort
Run Code Online (Sandbox Code Playgroud)
但当你真的想做的不仅仅是简单的回声时,这就变得很糟糕了。
下一个代码将在以下位置失败IF 1 NEQ 2
echo dummy | (
for /f "delims=" %%L in ('more') DO @(
echo # %%L
if 1 NEQ 2 echo Not Equal
)
)
Run Code Online (Sandbox Code Playgroud)
这有不同的(复杂的)原因,您可以阅读为什么在管道代码块内延迟扩展失败?当我通过管道传输 IF 命令时会发生什么?
为了能够毫无问题地使用循环,您可以使用调用函数包装器。
@echo off
REM *** This "goto" to a label, if there is one embedded in %~0 -
FOR /F "delims=: tokens=3" %%L in ("%~0") do goto :%%L
REM *** The second part calls this batch file, but embedd a label to be called
echo dummy | call %~d0\:myFunc:\..\%~pnx0 | sort
exit /b
REM *** This function will be called in the pipe, but runs in batch context
:myFunc
for /f "delims=" %%L in ('more') DO @(
echo # %%L
if 1 NEQ 2 echo Not Equal
)
exit /b
Run Code Online (Sandbox Code Playgroud)
自调用的工作原理:
call %~d0\:myFunc:\..\%~pnx0
Run Code Online (Sandbox Code Playgroud)
这会扩展到批次的完整路径,假设批次是,C:\temp\myFile.bat那么结果将是:
call C:\:myFunc:\..\temp\myFile.bat
这很奇怪,但仍然是一个有效的路径,因为:myFunc:不会被评估,因为该\..\部分将删除前一部分。
所以批处理文件调用自身。
诀窍是,它:myFunc:仍然是 %0 变量的一部分。
FOR /F "delims=: tokens=3" %%L in ("%~0") do goto :%%L
这部分将%0by拆分:为
"C", "\", "myFunc" and "\..\temp\myFile.bat"
并使用第三个标记 ( myFunc) 表示goto %%L。
这种技术的优点是,它不会破坏现有的批处理文件及其参数处理。
您也可以将该函数放入其中%1,但很难猜测该批处理是否应用%1作转到目标或将其用作普通参数。
| 归档时间: |
|
| 查看次数: |
1736 次 |
| 最近记录: |