[英]Bash quote behavior and sed
I wrote a short bash script that is supposed to strip the leading tabs/spaces from a string: 我写了一个简短的bash脚本,它应该从字符串中去掉前导标签/空格:
#!/bin/bash
RGX='s/^[ \t]*//'
SED="sed '$RGX'"
echo " string" | $SED
It works from the command line, but the script gets this error: 它可以从命令行运行,但脚本会收到此错误:
sed: -e expression #1, char 1: unknown command: `''
My guess is that something is wrong with the quotes, but I'm not sure what. 我的猜测是引号有问题,但我不确定是什么。
It does. 确实如此。 Try: 尝试:
#!/bin/bash
RGX='s/^[ \t]*//'
#SED='$RGX'
echo " string" | sed "$RGX"
This works. 这有效。
The issue you have is with quotes and spaces. 你遇到的问题是引号和空格。 Double quoted strings are passed as single arguments. 双引号字符串作为单个参数传递。
Add set -x
to your script. 将set -x
添加到脚本中。 You'll see that variables within a single-quote mark are not expanded. 您将看到单引号内的变量未展开。
Putting commands into variables and getting them back out intact is hard, because quoting doesn't work the way you expect (see BashFAQ #050, "I'm trying to put a command in a variable, but the complex cases always fail!" ). 将命令放入变量并将它们完整地取出是很困难的,因为引用不按预期方式工作(参见BashFAQ#050,“我试图将命令放在变量中,但复杂的情况总是失败!” )。 There are several ways to deal with this: 有几种方法可以解决这个问题:
1) Don't do it unless you really need to. 1)除非你真的需要,否则不要这样做。 Seriously, unless you have a good reason to put your command in a variable first, just execute it and don't deal with this messiness. 说真的,除非你有充分的理由将命令放在变量中,否则执行它并不处理这种混乱。
2) Don't use eval
unless you really really really need to. 2)除非你真的 真的需要,否则不要使用eval
。 eval
has a well-deserved reputation as a source of nasty and obscure bugs. eval
作为令人讨厌和模糊的错误的来源享有当之无愧的声誉。 They can be avoided if you understand them well enough and take the necessary precautions to avert them, but this should really be a last resort. 如果你足够了解它们并采取必要的预防措施来避免它们,就可以避免它们,但这应该是最后的手段。
3) If you really must define a command at one point and use it later, either define it as a function or an array. 3)如果你真的必须在一个点定义一个命令并在以后使用它,要么将它定义为函数或数组。 Here's how to do it with a function: 以下是使用函数执行此操作的方法:
RGX='s/^[ \t]*//'
SEDCMD() { sed "$RGX"; }
echo " string" | SEDCMD
Here's the array version: 这是阵列版本:
RGX='s/^[ \t]*//'
SEDCMD=(sed "$RGX")
echo " string" | "${SEDCMD[@]}"
The idiom "${SEDCMD[@]}"
lets you expand an array, keeping each element a separate word, without any of the problems you're having. 成语"${SEDCMD[@]}"
允许您扩展数组,将每个元素保持为单独的单词,而不会出现任何问题。
+To expand on my comment above: +要扩展我上面的评论:
#!/bin/bash
RGX='s/^[[:space:]]+//'
SED="sed -r '$RGX'"
eval "printf \" \tstring\n\" | $SED"
Note that this also makes your regex an extended one, for no particular reason. 请注意,这也使得你的正则表达式是一个扩展的,没有特别的原因。 :-) :-)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.