为什么当我在命令中使用变量时它停止工作? || 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,用于前瞻构造 (?=...)
。
早上好,我是脚本世界的新手,我遇到了这个问题,我不知道为什么会发生在我身上,为什么我会出错,在此先感谢。
例如,我有这个搜索字母少 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,用于前瞻构造 (?=...)
。