结果
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 shopt
Linux 和 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_bar
orvar1
例如或
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”关键字,它继续工作。 - 挠我的头。如果这浪费了任何人的时间,我深表歉意。