在递归操作中获取部分路径

在递归操作中获取部分路径

我有一个像这样的目录树

c:\work\src\A\D1\foo.txt
c:\work\src\A\D2\foo.txt
c:\work\src\B\foo.txt

我想为每个 foo.txt 运行流编辑器 (sed),并用 sed 替换一些文本。目标将如下所示:

c:\work\dst\A\D1\foo.txt
c:\work\dst\A\D2\foo.txt
c:\work\dst\B\foo.txt

我尝试使用 Windows 命令处理器的 for 命令查找所有 foot.txt,但我不知道如何从基目录中获取该部分:

cd c:\work\src
FOR /R %d in (sources) DO sed %d > c:\work\dst\%d

这不起作用,因为 %d 扩展为c:\work\src\A\D1\foo.txt而不是A\D1\foo.txt

我如何遍历所有文件并适当地构建目标路径?

编辑

我使用 sed,我也可以用它来处理路径名。我可以将路径名存储在一个文件中,以便 sed 对其进行修补:

set dst=c:\work\dst\
del /f foo.tmp
FOR /R %%d in (.) DO @echo %%d >> foo.tmp
sed s/C:\\work\\src\\// foo.tmp > bah.tmp
FOR /F IN (bah.tmp) DO sed -f patch.sed %%i > %dst%\%%i
del foo.tmp bah.tmp

这种方法的缺点是无法获取当前目录,%CD%但必须进行硬编码,因为 sed 需要转义反斜杠。此外,我还必须处理临时文件。有没有更优雅的方法,比如

FOR /R "c:\work\src" /D %%d IN (foo.txt) DO @if exist %%d  sed ????

答案1

与 Kevin 的剧本概念相同。只是稍微短一点。:-)

@echo off
::Get the directory from whence the script was called
set CWD=%~dp0
set CWD
for /R %%g in (foo.txt) do (if exist "%%g" call :GetPath "%%g")
goto :exit  

:GetPath
if not exist "%~1" goto :EOF
echo Original: %~1
set _nfile=%~1
call set _nfile=%%_nfile:%CWD%=%%
echo NFile: %_nfile%
goto :EOF

:exit
set CWD=
set _nfile=

在“GetPath”例程中添加 SED 命令并传递_nfile变量。

答案2

好的,我设置了同一组测试文件:

X:\>dir /s /b
X:\work
X:\work\src
X:\work\src\A
X:\work\src\B
X:\work\src\A\D1
X:\work\src\A\D2
X:\work\src\A\D1\foo.txt
X:\work\src\A\D2\foo.txt
X:\work\src\B\foo.txt

然后,我有一个批处理文件。假设它保存为"D:\batchscript.cmd"::

@echo off

rem get the "unique" part of the source and dest paths: "\src\", "\dst\"
set "zusource=\src\"
set "zudest=\dst\"



rem From within the current directory, and all subdirectories,
rem process each file named "foo.txt"
for /f "usebackq delims=" %%f in (`dir /s /b "foo.txt"`) do call :work "%%~f"

rem We are done. Go "exit" the script.
goto :EOF



:work
rem get the full name of the current "source" file: "X:\work\src\A\D1\foo.txt"
set "zsourcefq=%~1"



rem substitute the "unique" parts:
rem get "X:\work\dst\A\D1\foo.txt" from "X:\work\src\A\D1\foo.txt"
for /f "usebackq delims=" %%g in (`echo set "zdestfq=%%zsourcefq:%zusource%=%zudest%%%"`) do %%g



rem make the destination directory if necessaary: "X:\work\dst\A\D1"
rem two ways, first relies on your specific file "name", second is "universal"

rem md "%zdestfq:foo.txt=%" 2>nul
for %%g in ("%zdestfq%") do md "%%~dpg" 2>nul



echo Processing: "%zsourcefq%" --^> "%zdestfq%"

rem do your "sed" command here
echo     sed -r "s/whatever/whateverelse/g" "%zsourcefq%" ^> "%zdestfq%"

goto :EOF

要使用该脚本,首先更改到“源”目录:

X:\>CD /D "X:\work\src"
X:\work\src>

然后运行脚本:

X:\work\src>"D:\batchscript.cmd"
Processing: "X:\work\src\A\D1\foo.txt" --> "X:\work\dst\A\D1\foo.txt"
    sed -r "s/whatever/whateverelse/g" "X:\work\src\A\D1\foo.txt" > "X:\work\dst\A\D1\foo.txt"
Processing: "X:\work\src\A\D2\foo.txt" --> "X:\work\dst\A\D2\foo.txt"
    sed -r "s/whatever/whateverelse/g" "X:\work\src\A\D2\foo.txt" > "X:\work\dst\A\D2\foo.txt"
Processing: "X:\work\src\B\foo.txt" --> "X:\work\dst\B\foo.txt"
    sed -r "s/whatever/whateverelse/g" "X:\work\src\B\foo.txt" > "X:\work\dst\B\foo.txt"

将以:开头的行更改"echo sed -r..."为您需要的任何 sed 命令。

相关内容