简体   繁体   English

Bash引用行为和sed

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM