【问题标题】:Why when I use a variable in the command does it stop working? || Shell Scripting [duplicate]为什么当我在命令中使用变量时它会停止工作? || Shell 脚本 [重复]
【发布时间】:2021-06-02 10:27:20
【问题描述】:

早上好,我是脚本领域的新​​手,我遇到了这个问题,我不知道为什么会发生这种情况以及为什么我会出错,提前谢谢。

例如,我有这个命令可以搜索字母少 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:awk -F: -v number=4 'length($1) &lt;= number { print $1 }' /etc/passwdcut 不是必需的。

标签: linux bash shell command-line scripting


【解决方案1】:

考虑使用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

【讨论】:

    【解决方案2】:

    你需要使用双引号:

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

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

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

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

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

    【讨论】:

    • $1 也可能会被解释。
    • 啊,好点,你需要逃避它。让我更新一下问题。
    【解决方案3】:

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

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

    另一个单行,只使用grep 将是

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多