【问题标题】:parsing urls from windows batch file从 Windows 批处理文件中解析 url
【发布时间】:2012-09-01 18:53:25
【问题描述】:

我有一个文本文件 (myurls.txt),其内容是如下 URL 列表:

Slides_1:   http://linux.koolsolutions.com/svn/ProjectA/tags/REL-1.0
Exercise_1: http://linux.koolsolutions.com/svn/Linux/tags/REL-1.0

Slides_2:   http://linux.koolsolutions.com/svn/oldproject/ProjectB/tags/REL-2.0
Exercise_2: http://linux.koolsolutions.com/svn/ProjectB/tags/REL-1.0

Exercise_3: http://linux.koolsolutions.com/svn/BlueBook/ProjectA/tags/REL-1.0

现在我想在 for 循环中解析这个文本文件,以便在每次迭代之后(例如,从上述文件中获取第一个 url)我将以下信息放入不同的变量中:

%i% = REL-1.0
%j% = http://linux.koolsolutions.com/svn/ProjectA
%k% = http://linux.koolsolutions.com/svn/ProjectA/tags/REL-1.0

经过一些实验,我得到了以下代码,但它仅在 URL 具有相同数量的斜杠时才有效:

@echo off
set FILE=myurls.txt
FOR /F "tokens=2-9 delims=/ " %%i in (%FILE%) do (
@REM <do something with variables i, j and k.>
)

显然,我需要使它更灵活,以便它可以处理任意 url 长度。我对其他解决方案很好,例如使用 Windows Script Host/VBscript,只要它可以在默认的 Windows XP/7 安装下运行。换句话说,我知道我可以在 Windows 上使用 awk、grep、sed、python 等并完成工作,但我不希望用户必须安装除了标准 Windows 安装之外的任何东西。

【问题讨论】:

    标签: vbscript batch-file


    【解决方案1】:

    我认为这可能是您正在寻找的内容,但我不确定您的项目识别规则是什么。

    它使用 FOR ~pnx 修饰符来解析路径的一部分。从命令行使用HELP FOR 获取更多信息。它使用\..\.. 到达祖父“目录”,并在前面添加\ 以使“路径”成为绝对路径。

    结果将/// 转换为\,因此使用变量搜索和替换来恢复正确的斜杠分隔符,并使用子字符串操作去除前导斜杠。在命令行中使用HELP SET 以获取有关搜索和替换以及子字符串操作的更多信息。

    使用延迟扩展是因为它需要扩展在同一代码块中设置的变量。

    @echo off
    setlocal enableDelayedExpansion
    set "file=myurls.txt"
    for /f "tokens=1*" %%A in (%file%) do (
      for /f "delims=" %%C in ("\%%B\..\..") do (
        set "project=%%~pnxC"
        set "project=!project:~1!"
        set "project=!project:\=/!"
        set "project=!project:http:/=http://!"
        echo header  = %%A
        echo url     = %%B
        echo project = !project!
        echo release = %%~nxB
        echo(
      )
    )
    

    以下是您的示例数据的结果:

    header  = Slides_1:
    url     = http://linux.koolsolutions.com/svn/ProjectA/tags/REL-1.0
    project = http://linux.koolsolutions.com/svn/ProjectA
    release = REL-1.0
    
    header  = Exercise_1:
    url     = http://linux.koolsolutions.com/svn/ProjectA/tags/REL-1.0
    project = http://linux.koolsolutions.com/svn/ProjectA
    release = REL-1.0
    
    header  = Slides_2:
    url     = http://linux.koolsolutions.com/svn/oldproject/ProjectB/tags/REL-2.0
    project = http://linux.koolsolutions.com/svn/oldproject/ProjectB
    release = REL-2.0
    
    header  = Exercise_2:
    url     = http://linux.koolsolutions.com/svn/ProjectB/tags/REL-1.0
    project = http://linux.koolsolutions.com/svn/ProjectB
    release = REL-1.0
    
    header  = Exercise_3:
    url     = http://linux.koolsolutions.com/svn/BlueBook/ProjectA/tags/REL-1.0
    project = http://linux.koolsolutions.com/svn/BlueBook/ProjectA
    release = REL-1.0
    

    【讨论】:

    • 感谢您的回复!实际上没有确定项目的规则。事实上,这些 URL 中甚至可能没有名称 Project。例如,一个 URL 可以简单地是:linux.koolsolutions.com/svn/LinuxMaterial/tags/REL-1.0。唯一的形式是每个 URL 都有标题(如 Slides_N 或 Exercise_N)并以 /tags/REL-X.Y 结尾。
    • @modest - 这是一条规则 :-) 谢天谢地,它也与我实施的规则兼容。我剥离了最后 2 个路径组件来获取项目,这将与“/tags/REL-X.Y”相对应。在我看来,您的问题已得到解答。
    【解决方案2】:
    @echo off
    
    :: First seperate into Label, URI type, and internet path
    for /f "tokens=1-3 delims=:" %%x in (URLs.txt) do (
      echo.
    
      :: Take the Label
      for /f %%a in ("%%x") do set LabelNam=%%a
    
      :: Assemble Release URL
      set ReleaseURL=http:%%z
    
      :: Delayed variable expansion is required just for 'z'
      setlocal enabledelayedexpansion
    
        :: Take Release URL Path
        set z=%%z
    
        :: Extract the Release
        for /f "tokens=2" %%b in ("!z:/tags/= !") do set Release=%%b
    
        :: Split the Internet Path at the '/''s and call ':getURL'
        call :getURL %%y !z:/= !
    
        :: Output the information 
        echo       Label = !LabelNam!
        echo     Release = !Release!
        echo         URL = !URL!
        echo Release URL = !ReleaseURL!
      :: End variable expansion
      endlocal
    )
    goto :eof
    
    
    :getURL
      :: Get URL type
      set URL=%1:/
      :: shift all arguments one to the left
      shift
    
      :URLloop
        :: Assemble URL
        set URL=%URL%/%1
        shift
      :: If we haven't fount 'tags' yet, loop
      if "%1" neq "tags" goto :URLloop
    
    goto :eof
    

    【讨论】:

    • 很抱歉花了这么长时间发帖,但我被一个非常奇怪的错误分心了。如果您在:: Extract the Release 上方添加另一个以冒号分隔的注释,我会收到The system cannot find the drive specified. 错误。只需一对冒号即可。但是将:: 替换为REM,就可以了。我玩过它并得到了不同的错误。真是太BIZZARE了。而且我还没有弄清楚发生了什么。
    • BIZZARE 效果来自括号内的主要/次要标签行SO: windows batch file with goto command not working
    • @jeb - 哎呀,我应该知道的!我记得:: 之前破坏了我的代码,使代码表现得像括号外一样。谢谢你提醒我。 ^_^
    • @jeb - 说,我也遇到了麻烦:for /f "tokens=* delims=/" %%x in ("http://somesite.com/path/whatever") do echo %%x 因为它总是会回显整个 URL,而不是拆分它。但如果我指定令牌,它会起作用。你知道这是否只是for 中的一个错误吗?
    • 这不是错误,tokens=* 被解释为具有完整内容的 ONE 令牌,您必须在 tokens= 选项中声明每个令牌才能访问稍后,但您可以跳过一些标记,例如 tokens=1,4,7,*
    【解决方案3】:

    好的,我最简短、最容易理解但评论最少的解决方案:

    @echo off
    for /f "tokens=1-3 delims=: " %%x in (URLs.txt) do (
      set LabelNam=%%x
      set ReleaseURL=%%y:%%z
      for /f "tokens=1-31 delims=/" %%a in ("%%y:%%z") do call :getURL %%a %%b %%c %%d %%e %%f %%g %%h %%i %%j %%k %%l %%m %%n %%o %%p %%q %%r %%s %%t %%u %%v
      echo.
      echo       Label = %LabelNam%
      echo     Release = %Release%
      echo         URL = %URL%
      echo Release URL = %ReleaseURL%
    )
    goto :eof
    
    :getURL
      set URL=%1/
      shift
      :URLloop
        set URL=%URL%/%1
        shift
      if "%1" neq "tags" goto :URLloop
      Set Release=%2
    goto :eof
    

    【讨论】:

      猜你喜欢
      • 2011-06-04
      • 2014-07-12
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多