如何在FOR / F的引号内的命令中包含引号

时间:2015-10-02 22:30:16

标签: windows batch-file for-loop sed cmd

这很好用。

 FOR /f "delims=" %%G in ('TagRead.exe %%L Genre') DO ( echo %GG )

但是当我向('...')添加sed命令时,它失败了

 FOR /f "delims=" %%G in (
 'TagRead.exe %%L Genre ^| sed -E ''/Curtain^|Exit^|Spacer/^^!s~.*~Dance~'' '
 ) DO ( echo %%G)

输出:

 sed: newline or end of file found in pattern

编辑:尽管这个无循环命令成功了:

  TagRead.exe C:\temp\1.wma Genre | sed -E '/Curtain^|Exit^|Spacer/^!s~.*~Dance~'

如何在(...)引号中接受sed命令及其引号?

编辑:dbenham说:“当与FOR / F一起使用时,单引号永远不需要被转义。最外面的单引号分隔命令字符串,任何内部单引号都可以正常工作。”

这是解决方案:

FOR /f "delims=" %%G in (
'TagRead.exe %%L Genre ^| sed -E '/Curtain^|Exit^|Spacer/^^!s~.*~Dance~''
) DO ( echo %%G)

失败了:

The syntax of the command is incorrect.

编辑:这是一个简化的独立版本,希望能解决这个问题:

FOR /f "delims=" %%G in (
'echo xxx ^| sed -E '/yyy/^^!s~.*~zzz~''
) DO ( echo %%G)

成功:

zzz

此:

echo xxx | sed -E '/yyy^|uuu/^!s~.*~zzz~'

成功:

zzz

此:

FOR /f "delims=" %%G in (
'echo xxx ^| sed -E ''/yyy^|uuu/^^!s~.*~zzz~'''
) DO ( echo %%G)

失败:

'uuu' is not recognized as an internal or external command, operable program or batch file.

-----------解决方案-----------

失败的原因不是报价。这是一些不充分逃脱^。从dbenham的1),最小的修复是:

FOR /f "delims=" %%G in (
'TagRead.exe %%L Genre ^| sed -E ''/Curtain^^^|Exit^^^|Spacer/^^!s~.*~Dance~'' '
) DO ( echo %%G)

和简化版:

FOR /f "delims=" %%G in (
'echo xxx ^| sed -E ''/yyy^^^|uuu/^^!s~.*~zzz~'''
) DO ( echo %%G)

还可以删除一些冗余的':

FOR /f "delims=" %%G in (
'TagRead.exe  %%L Genre ^| sed -E '/Curtain^^^|Exit^^^|Spacer/^^!s~.*~Dance~' '
) DO ( echo %%G)

FOR /f "delims=" %%G in (
'echo xxx ^| sed -E '/yyy^^^|uuu/^^!s~.*~zzz~''
) DO ( echo %%G)

编辑:实例中的解决方案仍然更简单:

FOR /f "delims=" %%G in ('echo "xxx^^^|ppp" ^| find "x^^^|p"') DO ( echo %%G)

2 个答案:

答案 0 :(得分:2)

FOR / F通过新的cmd.exe进程运行命令。

例如:

for /f %%A in ('echo hello') do echo %%A

FOR / F使用以下命令运行命令:

C:\Windows\system32\cmd.exe /c echo hello

在发布此消息时,仍未在问题中正确发布所需命令。让我们假设正确的操作命令如下(对我来说没有意义)

TagRead.exe C:\temp\1.wma Genre | sed -E '/Curtain^|Exit^|Spacer/^^!s~.*~Dance~'

您希望将命令放在FOR / F循环中。

您有两种选择。

1)您可以转义所有有毒字符,以便它们正确地通过cmd.exe命令:

for /f "delims=" %%G in ('TagRead.exe C:\temp\1.wma Genre ^| sed -E '/Curtain^^^|Exit^^^|Spacer/^^!s~.*~Dance~'') do echo %%G

我猜您最初将!转义为^^!,因为您已启用延迟扩展。新的cmd.exe进程将禁用延迟扩展,因此您不需要为此构造进行其他转义。

2)或者您可以使用CMD.EXE在使用/ C命令时删除最外面的双引号这一事实。您需要做的就是添加双引号: - )

for /f "delims=" %%G in ('"TagRead.exe C:\temp\1.wma Genre | sed -E '/Curtain^|Exit^|Spacer/^!s~.*~Dance~'"') do echo %%G

在这种情况下,必须在^之前移除!,因为扩展的延迟工作原理如下:引用转义! = "^!",且未加引号= {{1 }}

当然,以上所有都取决于原始命令(没有循环)是否有效。它看起来很可疑。无论如何,上面的概念适用于放入FOR / F循环的大多数工作命令。

答案 1 :(得分:1)

尝试使用usebackq http://ss64.com/nt/for_f.html

for /f "usebackq delims=" %%g in (
  `TagRead.exe %%L Genre ^
  ^| sed -E '/Curtain^|Exit^|Spacer/^^!s~.*~Dance~' `
  ) do ( echo %%g)

编辑: 删除双打单引号并保留一个。
但不确定如何在|命令

中转义sed

尝试在没有sed的情况下以这种方式双引usebackq模式:

for /f "delims=" %%g in (
  'TagRead.exe %%L Genre ^
  ^| sed -E "/Curtain^|Exit^|Spacer/^^!s~.*~Dance~" '
  ) do ( echo %%g)

编辑:
()和命令sed中有多个引号的示例,每'd'a'y'替换字符串'n'i'g'h't'

for /f "usebackq delims=" %g in ( 
  `echo 'd'a'y'^| sed "s/'d'a'y'/'n'i'g'h't'/"`
  ) do @( echo %g)

另一个转换Winter\SummerSummer\Winter

for /f "usebackq delims=" %g in ( 
  `echo Winter\Summer^| sed -r "s/(.*)\\(.*)/\2\\\1/"`
  ) do @( echo %g)