使用 awk 从 bash 函数查看我的小写 shell 变量

使用 awk 从 bash 函数查看我的小写 shell 变量

结果

set使用或过滤输出显示的变量,declare仅显示小写命名 shell这是我在测试时设置 shell 变量的约定。

例子

我设置了这些:

$ declare -A pid=()
$ a=DHCP
$ something=test

我希望输出看起来像这样:

$ lvar
a=DHCP
pids=()
something=test

我为该功能想出了这个 awk 命令lvar

declare | awk -F'=' '$1 ~ /^[a-z]+$/'

从命令行运行时效果非常好。但是,作为一个源自并运行的函数,我收到一个错误,我认为该错误是由awk的字段参数 $1被解释为bash函数参数

$ vi func
function lvar() {
  declare |awk -F'=' '$1 ~ /^[a-z]+$/'
}

跑步勒瓦尔给出这个错误:

$ lvar
awk: cmd. line:1:  ~ /^[a-z]+$/
awk: cmd. line:1:  ^ syntax error

我在这里做错了什么?

$ declare -p -f lvar
lvar () 
{ 
    declare | awk -F'=' '$1 ~ /^[a-z]+$/'
}

更新1

我最初的方法是awk 命令定义为bash函数,确实有效 - 仅在我的 Linux 机器上,而不是在我最初定义它的 Mac 上。

我得弄清楚macOS 问题并在适当的时候在这里向大家发布更新。
非常感谢您的宝贵时间:)

更新2

好的,我检查了bash shoptLinux 和 macOS 上的选项是否不同,但事实并非如此。

我在 Mac 上打开 iTerm,该函数的行为符合预期,但在 Terminal.app 中没有显示任何输出。

非常奇怪的是,它特定于 Terminal.app 中的某些设置。我不知所措。

答案1

使用bash,您可以使用以下命令将变量名称列表(尽管不是已声明但未分配的变量名称)放入数组中:

readarray -t Vars < <(compgen -v)

您可以使用以下方法过滤它grep

readarray -t Vars < <(compgen -v | grep -x '[[:lower:]]*') &&
  [ "${#Vars[@]}" -gt 0 ] &&
  declare -p -- "${Vars[@]}"

例如,对于全小写的。

grep将过滤器更改grep -v '[[:upper:]]'为适用于除名称包含大写字母的变量或grep '[[:lower:]]' | grep -v '[[:upper:]]'至少包含一个小写字母且没有大写字母的变量之外的所有变量。

在任何情况下,您都无法declare像您尝试那样对逐行的输出进行后处理,因为变量值很可能由多行组成,并且至少在posix启用该选项时,bash会显示它们(至少是标量)例如:

var='line 1
line 2'

禁用该posix选项后,5.1 似乎bash至少总是呈现换行符,因为$'\n'这将保证每个变量定义都在一行上。

在这种情况下,你可以这样做:

(set +o posix; declare | grep -E '^[[:lower:]]+=')

列出名称全小写的变量的定义(假设变量值足够短或者不会因grep大于LINE_MAX字节的行而阻塞)。

与 for 一样compgen -v,它不包括声明的未分配的变量。

答案2

zsh

set -o extendedglob
typeset -m '[[:lower:]]#'

将打印名称完全由小写字母组成的变量的定义。

set -o extendedglob
typeset -m '^*[[:upper:]]*'

对于不包含大写字母的内容,还包括foo_barorvar1例如或

set -o extendedglob
typeset -m '*[[:lower:]]*~*[[:upper:]]*'

对于那些至少包含一个小写字母且不包含大写字母的变量,要排除名为___123_或 等名称的变量字母与前一个相比,它没有小写或大写形式。

请注意zsh完成定义了很多这样的变量。

答案3

好吧,我的函数方法成立了。有一些疯狂的 Terminal.app 问题这与功能无关。

从:

$ vi ~/.bash_functions
lvar() {
  declare |awk -F'=' '$1 ~ /^[a-z]+$/'
}

到:

$ vi ~/.bash_functions
function lvar() {
  declare |awk -F'=' '$1 ~ /^[a-z]+$/'
}

我真的希望我能指出问题所在,但它开始起作用终端程序在我使用长函数定义格式之后功能关键字,在我的主 bash 函数文件中,关闭 Terminal.app 并重新打开它。嘿,快点 - 它成功了!然后删除了我的主要 bash 函数中的“function”关键字,它继续工作。 - 挠我的头。如果这浪费了任何人的时间,我深表歉意。

相关内容