2

我将如何实现这一目标:

for i in *.e; do mv $i ${i%-b*.e}.e; done

在 Windows 批处理文件中?(它将包含“-b”的文件重命名为“-b”之前的部分。请注意,这不一定是字符串的结尾!例如“file-b-4.e”将变为“file.e”)

4

3 回答 3

5

如果您真的想批量执行此操作,则应该可以

@echo off
setlocal disableDelayedExpansion
for %%F in (*.e) do (
  set "var=%%~F"
  setlocal enableDelayedExpansion
  set "var=!var:-b=.e:!"
  for /f "eol=: delims=:" %%A in ("!var!") do (
    endlocal
    echo ren "%%F" "%%A"
  )
)

编辑
panda-34 的评论暗示如果文件名以-b. 上面的代码是通过将扩展合并到替换字符串中来修复的。(感谢 panda-34 提醒我这个问题)

panda-34 还提供了一个替代解决方案,它使用带有搜索和替换的命令注入。注入的命令是 REM 语句。

只要文件名不包含&^字符,panda-34 解决方案就可以工作,但如果包含,则会失败。

下面是命令注入技术的修改版本,它应该适用于所有有效的 Windows 文件名。有 2 个关键模块,1)确保文件名中的特殊字符始终被引用,2)不要将值作为 CALL 参数传递,否则^将加倍为^^.

@echo off
setlocal disableDelayedExpansion
for %%i in (*-b*.e) do (
  set old="%%~ni"
  call :ren_b
)
exit /b
:ren_b
set v=%old:-b=.e"&rem "%
echo ren "%old:~1,-1%.e" %v%
exit /b

最终编辑(我希望):
正如巴鲁克在他的评论中指出的那样,上面的解决方案从第一次出现开始删除,而原始 bash 命令从最后一次出现开始删除。

下面是一个与原始 bash 命令完全等效的版本。

@echo off
setlocal disableDelayedExpansion
set "search=-b"
for %%A in (*%search%*.e) do (
  set "old=%%A"
  setlocal enableDelayedExpansion
  set "new=\_!old:%search%=\_!"
  for %%B in ("!new!") do (
    endlocal
    set "new=%%~pB"
    setlocal enableDelayedExpansion
    set "new=!new:~2,-1!.e"
    echo ren "!old!" "!new:\_=%search%!"
    endlocal
  )
)
于 2012-05-24T15:44:14.007 回答
3

简单,真的

for %%i in (*-b*.e) do call :ren_b %%~ni
goto :eof
:ren_b
set v=%*
set v="%v:-b=.e" ^& rem %
ren "%*.e" %v%

这是一个将名称保留到最后一次出现的变-b

setlocal enabledelayedexpansion
for %%i in (*-b*.e) do (
    set v=%%~ni
    set v=!v:-b=\!
    for %%j in ("\!v!") do (
        set v=%%~pj
        set v=!v:~1,-1!
        set v=!v:\=-b!
        ren "%%i" "!v!.e"
    )
)

!对于包含并以 . 开头的名称,它将失败-b

PS,没看到,dbenham 已经提供了等效的解决方案,可能对文件名的终端情况有更多的规定。

于 2012-05-24T18:01:00.940 回答
2

算了,一些方便的事情在 NT 脚本中是做不到的。据我所知,你在这里问的是不可能的。而且我使用各种技巧编写和维护了大于 50 KiB 的复杂 NT 脚本。“Windows NT Shell Scripting”一书指出了其中的许多内容,同样的内容和更多内容请参见Rob van der Woude 的脚本页面

我认为您可以完成其中的一部分,但由于变量扩展在 NT 脚本中的工作方式,因此肯定不能单行。例如,您可以提取您期望的字符串部分-b并检查它是否为-b,然后提取其他部分并将原始名称重命名为仅由提取部分组成的名称。

但是你可能需要十到十五行来实现这一点。鉴于此,请考虑为此目的使用不同的脚本语言。特别是如果这是现代 Windows 版本。

我意识到这不是想要的答案(即这是可能的并且是一个示例),但cmd.exe与 Bash 相比非常有限,尽管远没有传统批处理脚本的一些反对者指出的那样有限。

于 2012-05-24T14:18:15.720 回答