为什么当我在命令中使用变量时它停止工作? || Shell 脚本

Why when I use a variable in the command does it stop working? || Shell Scripting

早上好,我是脚本世界的新手,我遇到了这个问题,我不知道为什么会发生在我身上,为什么我会出错,在此先感谢。

例如,我有这个搜索字母少 X 的用户的命令:

cut -d: -f1 /etc/passwd | awk 'length() <= 4'

它工作正常,但是当我用 4 替换具有相同值的变量时它不能很好地工作:

number=4
echo -e $(cut -d: -f1 /etc/passwd | awk 'length() <= $number')

同样的错误也发生在我这里,当我搜索有旧密码的用户时

awk -F: '{if(<=18388)print}' < /etc/shadow

有效,但当我使用变量时它停止工作

variable=18388
awk -F: '{if(<=$variable)print}' < /etc/shadow

您需要使用双引号:

echo -e $(cut -d: -f1 /etc/passwd | awk "length($1) <= $number")

在单引号中,变量不被解释。

更新:这是一个说明性示例:

> X=1; echo '$X'; echo "$X"
$X
1

更新 2:正如评论中正确指出的那样,当使用双引号时,需要确保 awk 解释的变量被转义,因此它们不会在脚本评估期间被解释.上面更新了命令。

考虑使用 awk's 通过 -v 选项导入变量的能力,例如:

number=4
cut -d: -f1 /etc/passwd | awk -v num="${number}" 'length() <= num'

虽然/etc/passwd的第一个字段包含白色space,并且您要考虑整个字段的长度,您应该将</code>替换为<code>[=17=] ,例如:

number=4
cut -d: -f1 /etc/passwd | awk -v num="${number}" 'length([=11=]) <= num'

更好的是,通过将输入字段分隔符指定为冒号,消除 cut 和子流程(由于管道)并在整个操作中使用 awk

number=4
awk -F':' -v num="${number}" 'length() <= num { print  }' /etc/passwd

或者,这个任务可以只使用一个 GNU sed 一行来完成:

num=4
sed -E "s/:.*//; /..{$num}/d" /etc/passwd

另一种单行,仅使用 grep 将是

grep -Po "^[^:]{1,$num}(?=:)" /etc/passwd

但这需要支持 perl 正则表达式的 grep,用于前瞻构造 (?=...)