存储在变量中的剪切命令将不起作用

存储在变量中的剪切命令将不起作用

有人可以解释为什么我不能将 cut 命令存储在变量中吗?

user:~$ echo "foo bii doo" | cut -d ' ' -f 2
bii # as expected
# now put cut command into a variable:
user:~$ c="cut -d ' ' -f 2"
user:~$ echo "foo bii doo" | $c
cut: "'": No such file or directory
user:~$ c="cut -d \  -f 2"
user:~$ echo "foo bii doo" | $c
foo bii doo

这不是一般的引用问题,因为 tr 有效:

user:~$ t="tr -d 'oo'"
user:~$ echo "foo bii doo" | $t
f bii d

(我在 Debian 12 上使用 bash)
已经用其他方式解决了这个问题。我只是想知道为什么我浪费了 3 个小时的调试时间:)

答案1

在某种程度上,这不是一个引用问题,而是一个扩展问题。变量扩展不是文本替换,从变量中获取的数据是不是解析为代码,这意味着引号、反斜杠转义或任何其他 shell 语法都不会被处理。相反,扩展值是在空白(任何空白)上进行分词的。这意味着您不能使用分词在一个字符串中存储多个任意字符串。

tr您使用的命令似乎工作,因为在其参数中添加单引号不会改变它对os 的作用。正如克里斯戴维斯在评论中提到的,如果你这样做:

$ t="tr -d 'oo'"
$ echo "don't forget" | $t
dnt frget

tr您将看到引号已包含在要删除的字符列表中。tr得到了论据'oo',而不是论据oo。如果您想tr删除空格,则会遇到问题,与以下情况相同cut

$ t="tr -d ' '"
$ echo "don't forget" | $t
usage: tr [-Ccsu] string1 string2
       tr [-Ccu] -d string1
       tr [-Ccu] -s string1
       tr [-Ccu] -ds string1 string2

它尝试tr使用三个参数-d'和来运行',这与它应该如何使用不匹配,因此它会打印使用帮助。

做到这一点的方法是创建一个函数,例如:

c() {
    cut -d \  -f 2
}
echo "foo bii doo" | c

给予bii

看:

相关内容