【问题标题】:How to extract, using cmd, string between quotes from a particular line如何使用cmd提取特定行的引号之间的字符串
【发布时间】:2017-08-14 15:39:30
【问题描述】:

希望我能清楚我的问题和我要搜索的内容。我在 .sjs 文件中有一个长脚本(基本上是具有不同扩展名的 txt),其中一部分是以下几行。在下面的 cmets 中,这被称为 input.txt 或 Builder.sjs

var Want_spring_aid_file_update = 0;
var Front_spring_aid_file = "name_1.pspck";
var Rear_spring_aid_file = "name_2.pspck";

我一直在寻找一个 .bat 脚本,它可以在这个 .sjs 文件中探测某些行,在上面的例子中是第 2 行和第 3 行,并将双引号之间的字符串写入一个文本新文件中。在下面的 cmets 中,这个新的文本文件被称为 cmets.txt。

我在这个了不起的网站上找到了一个脚本,它输出该文件中引号之间的所有字符串。我只想在特定的线路上。我说的脚本如下。

>"output.txt" (
 for /f usebackq^ tokens^=2^ delims^=^" %%A in ("input.txt") do echo "%%A" 
)

另外,如果有人可以帮助我理解上述脚本中某些角色的角色,那将很有帮助。这些是^、2^、^=^。

谢谢大家!

【问题讨论】:

  • 为什么不使用"input.txt" 而不是使用'FindStr [options] [search mask] "input.txt"' 来挑选与您所需的var 名称相关的数据?
  • 这可以用显示的数据来解决问题:for /F "skip=1 tokens=4 delims=; " %%a in (test.txt) do echo %%~askip=1 部分省略了第 1 行。"tokens=4 delims=; " 采用由空格或分号分隔的第 4 个标记。在%%~a 部分中包含一个波浪号表明这样一个标记删除了封闭的引号。

标签: batch-file


【解决方案1】:

@Compo 谢谢!下面的代码在经过一番反复试验后做到了。

@echo off
>>"comments.txt" ( 
    for /f usebackq^ tokens^=2^ delims^=^" %%A in ( 'findstr /C:var Front_spring_aid_file = ^"part_name1^"; "Builder.sjs"') do echo %%A
)

【讨论】:

  • findstr 命令行导致在文件Front_spring_aid_file=part_name1;Builder.sjs 中搜索字符串var。要查找带有变量Front_spring_aid_file 的行,必须使用例如findstr /C:"var Front_spring_aid_file =" "Builder.sjs",因为这会导致在文件Builder.sjs 中搜索包含字符串var Front_spring_aid_file = 的行。
  • 要搜索包含字符串var Front_spring_aid_file = "part_name1"; 的行,必须使用命令行findstr /L /C:"var Front_spring_aid_file = \"part_name1\";" "Builder.sjs"。但我怀疑搜索或多或少整行是否有意义,因为在这种情况下,findstr 的输出与搜索字符串相同。最好使用与findstr /R /C:"var  *Front_spring_aid_file *= *\"..*\";" "Builder.sjs" 一样的正则表达式。在命令提示符窗口中运行 findstr /? 以获取有关此正则表达式搜索的帮助。
  • @Mofi 。确实是复杂的东西。它确实有效,我相信它有效,因为开关 /C: 告诉 findstr 函数忽略后面字符串中的空格,因此它会上升到下一个 " 前面没有转义,在这个如果这是"Builder.sjs" 前面的“。如果我将其写为'findstr /C:"var Front_spring_aid_file = ^"part_name1^";" "Builder.sjs"',则表示sintax 不正确。顺便说一句,感谢您注意到我的小部件名称泄漏。
  • @Mofi 如果我将我的 findstr 替换为您建议的包含开关 /L 的那个,则输出为 var Front_spring_aid_file = \
  • 不,/C:"search string with spaces" 必须用于搜索还包含空格的文字字符串。尝试在包含文件Builder.sjs 的目录中的命令提示符窗口中仅运行findstr 命令行,就像我所做的那样。您只是认为它按预期工作,因为 FORFINDSTR 的错误输出过滤为预期输出。 FINDSTR 的搜索字符串中的转义字符是\。但这默认启用正则表达式搜索,这就是为什么还必须指定 /L 以显式请求文字搜索的原因。
【解决方案2】:

带有选项/F的命令FOR用于处理文件的行,或用双引号指定的单个字符串,或由FOR执行的命令行的输出strong> 在后台从后台命令进程的句柄 STDOUT 捕获的单独命令进程中。

第一个选项usebackq 导致将双引号中指定的文件名解释为要处理的字符串,而不是解释为 FOR 应处理其行的文件的双引号名称。

选项delims= 用于指定分隔符,用于将不以默认行尾字符; 开头的每个非空行拆分为一个或多个称为标记的子字符串。默认分隔符是空格和水平制表符。 delims= 没有任何字符意味着根本不拆分行。此任务只能使用双引号字符 " 作为分隔符。

选项tokens= 定义应将哪些子字符串分配给循环变量。默认情况下,只有第一个子字符串(令牌)被分配给指定的循环变量。通过指定tokens=2 命令FOR 被告知感兴趣的是应该分配给指定循环变量(第一个)的第二个子字符串。这也意味着,如果一行在 1 个或多个指定分隔符之后没有字符串,则该行也将被忽略。对于根本不包含双引号字符的input.txt 的第一行也是如此。

在命令提示符窗口for /? 中运行,以获取有关多页命令FOR 输出选项的更多信息。

FOR 的那些选项通常用双引号括起来。

>"output.txt" (
    for /F "usebackq tokens=2 delims="" %%A in ("input.txt") do echo "%%A" 
)

但这里的问题是将" 指定为分隔符。对于 Windows 命令解释器,选项字符串是 "usebackq tokens=2 delims=" 这没有多大意义,因为这意味着不应将行拆分为标记,但只有第二个标记是有意义的。但是,下一个" 无效,因为预期的下一个是循环变量,一个带有百分号的单个字符。百分号必须在带有附加百分号的批处理文件中进行转义。

因此,有必要指定 FOR 的选项,而不用双引号将它们括起来。因此,在执行FOR命令行之前,必须确保在Windows命令解释器的预处理阶段,这3个选项被解释为单个参数字符串。

在批处理文件中使用的转义字符是插入字符^,它指示 Windows 命令解释器将下一个字符解释为属于参数字符串的文字字符。只有% 必须用% 转义而不是^ 才能解释为文字字符。

它可以在命令提示符窗口cmd /? 在最后一个输出帮助页面的最后一段上运行时读取,目录/文件名(或其他参数字符串)中的字符需要用双引号括起字符串:空格字符,字符 &()[]{}^=;!'+,`~ 和帮助中未提及的字符 "|<> 不能在目录/文件名中使用。

因此,对于 Windows 命令解释器,usebackq^ tokens^=2^ delims^=^" 指定一个不包含在双引号中且带有异常文本 usebackq tokens=2 delims=" 的参数字符串应作为 @987654345 之后的第二个参数传递给命令 FOR @。

Windows 命令解释器将未使用^ 转义的空格字符和等号解释为参数字符串之间的分隔符。

未使用^ 转义的双引号被解释为以另一个双引号结尾的参数字符串的开头,并且在启用延迟扩展时,除了%! 之间的所有字符都被解释为文字字符.

这就是为什么空格字符、等号和双引号必须在参数字符串usebackq tokens=2 delims=" 中用^ 转义的原因。

有关 Windows 命令解释器的命令行解析的更多详细信息,请参阅How does the Windows Command Interpreter (CMD.EXE) parse scripts?

【讨论】:

  • 嗨莫菲!非常感谢您的澄清。我现在很清楚“^”的作用,但仍然对其位置有点怀疑。就像为什么出现在数字 2 之后和空格之前一样。然而,这确实说明了如何解决我的问题。然而,@Compo 提到的解决方案在经过反复试验后奏效了
猜你喜欢
  • 2012-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-05
  • 2023-03-06
  • 1970-01-01
  • 2021-09-19
相关资源
最近更新 更多