4

我需要在 Windows 批处理文件中,从文本文件中读取第一个可用行,将其传递给变量并将名称\行标记为已使用

该文件的示例如下。

苹果

该脚本将以“apple”开头,将“apple”传递给稍后在脚本中使用的变量(我知道该怎么做),然后写回该行以读取 &apple,“&”作为标记说它已被使用。

该文件将如下所示:

&苹果

下次运行批处理文件时,它将使用“pear”,将其传递给变量并用 & 标记它,使其看起来像:

&苹果
&梨

我首先尝试查找“&”,然后尝试移至下一行,但尝试了大约 12 小时后我失败了。这是我到目前为止所得到的......不多:

for /f "tokens=1" %l in ('name.txt') do (Find /v "&" /v "^---- ^$") (For /F %n in (%l) do (设置新名称=%n))

谢谢

4

2 回答 2

7

运行它the.file会依次修改每一行;

@echo off
setlocal enabledelayedexpansion
type nul > the.file.temp
set last=
for /F "tokens=*" %%A in (the.file) do (
    set line=%%A
    if "!line:~0,1!" neq "&" if "!last!" equ "" (
        set last=!line!
        set line=^&!line!
    )
    echo !line! >> the.file.temp
)

echo last value is !last!
type the.file.temp > the.file

(如果该行不以开头&且变量last为空,则将该行放入last& 修改line前导&。始终附加line到临时文件,完成后重命名)

于 2012-11-08T15:36:39.013 回答
4

亚历克斯·K。有一个很好的答案,在大多数情况下可能都很好。(我投了赞成票。)

但是,它会损坏任何包含!. 可以通过在循环内打开和关闭延迟扩展来修复该限制。

对于大多数合理大小的文件,该解决方案可能足够快。但是对于大文件,FOR 循环可能会变得非常慢。

我测试了一个包含 2817 行的 190kb 文件,Alex K. 解决方案一次运行需要 20 秒。

这是一个完全不同的解决方案,不使用在 0.07 秒内处理相同 190kb 文件的任何循环 - 快 285 倍 :)

@echo off
setlocal enableDelayedExpansion
set "file=test.txt"
findstr /bv "$ &" "%file%" >"%file%.available"
set "var="
<"%file%.available" set /p "var="
if defined var (
  >"%file%.new" (
    findstr /b "&" "%file%"
    <nul set /p "=&"
    type "%file%.available"
  )
  move /y "%file%.new" "%file%" >nul
)
del "%file%.available"

echo var=!var!


更新:根据评论中的要求,这里是代码的重注释版本。

@echo off
setlocal enableDelayedExpansion

:: Define the file to process
set "file=test.txt"

:: Write the unused lines to a temporary "available" file. We don't want any
:: empty lines, so I strip them out here. There are two regex search strings;
:: the first looks for empty lines, the second for lines starting with &.
:: The /v option means only write lines that don't match either search string.
findstr /bv "$ &" "%file%" >"%file%.available"

:: Read the first available line into a variable
set "var="
<"%file%.available" set /p "var="

:: If var defined, then continue, else we are done
if defined var (

  REM Redirect output to a "new" file. It is more efficient to redirect
  REM the entire block once than it is to redirect each command individulally
  >"%file%.new" (

    REM Write the already used lines to the "new" file
    findstr /b "&" "%file%"

    REM Append the & without a new line
    <nul set /p "=&"

    REM Append the unused lines from the "available" file. The first appended
    REM line is marked as used because of the previously written &
    type "%file%.available"
  )

  REM Replace the original file with the "new" content
  move /y "%file%.new" "%file%" >nul
)

:: Delete the temp "available" file
del "%file%.available"

:: Display the result
echo var=!var!


我没有对此进行测试,但我刚刚意识到我可以编写写入可用行的行来查找以以下字符开头的行&

findstr "^[^&]" "%file%" >"%file%.available"
于 2012-11-08T19:33:48.813 回答