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

问题描述

早上好,我是脚本世界的新手,我遇到了这个问题,我不知道为什么会发生在我身上以及为什么我有错,提前致谢。

例如,我有这样一个命令,可以搜索少 X 个字母的用户

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

它可以正常工作,但是当我用 4 替换具有相同值的变量时,效果不佳:

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

当我搜索使用旧密码的用户时,我也遇到了同样的错误

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

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

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

解决方法

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

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

虽然如果 /etc/passwd 的第一个字段包含空格,并且您想考虑整个字段的长度,则应该将 $1 替换为 $0,例如:

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

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

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

你需要使用双引号:

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

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

更新:这是一个说明性的例子:

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

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

,

或者,可以仅使用单个 GNU sed one-liner 来完成此任务:

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

另一种单行,仅使用 grep

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

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