在bash中列出文件中的所有变量

在bash中列出文件中的所有变量,bash,shell,associative-array,compgen,Bash,Shell,Associative Array,Compgen,在编写bash脚本时,我喜欢编写自包含函数,这些函数接受一个参数并基于该参数执行操作,而不是在代码中的几个不同位置声明全局变量,从而降低可读性 当您有一个需要使用多个变量的函数时,问题就会出现。将10个变量之类的东西传递给一个函数非常难看,因此可以使用一个简单的关联数组 如果我们想在外部文件中声明这些变量,“source”命令允许您将它们全部导入 接下来的问题是,如何列出仅在此文件中声明的变量,以便使用它们构建关联数组? 我已经能够使用“compgen”和循环的组合从变量列表中构建关联数组,但是

在编写bash脚本时,我喜欢编写自包含函数,这些函数接受一个参数并基于该参数执行操作,而不是在代码中的几个不同位置声明全局变量,从而降低可读性

当您有一个需要使用多个变量的函数时,问题就会出现。将10个变量之类的东西传递给一个函数非常难看,因此可以使用一个简单的关联数组

如果我们想在外部文件中声明这些变量,“source”命令允许您将它们全部导入

接下来的问题是,如何列出仅在此文件中声明的变量,以便使用它们构建关联数组?
我已经能够使用“compgen”和循环的组合从变量列表中构建关联数组,但是如何只列出文件中找到的变量,而不管它们被称为什么,因此,我可以循环使用它们并构建我的数组?

您可以对文件中的某个变量声明语法执行一次egrep,然后通过剪切来获取变量名,例如:

egrep '[a-zA-Z0-9"'\''\[\]]*=' /path/to/file |egrep -v '^#' |cut -d'=' -f1 |awk '{print $1}'
A
B
DEF
GHI1
JKL[1]
JKL['a']
JKL["b"]
for VAR in $(egrep '[a-zA-Z0-9"'\''\[\]]*=' /path/to/file |egrep -v '^#' |cut -d'=' -f1 |awk '{print $1}'); do
  eval echo "\$${VAR}"
done

如果您有一个包含这样内容的文件

#!/bin/bash

A="test"

somerandomfunction () {
        echo "test function"
        B="test"
}

#C="test"

DEF="test"
GHI1="test"
JKL[1]="test"
JKL['a']="test"
JKL["b"]="test"
上述命令的输出如下所示:

egrep '[a-zA-Z0-9"'\''\[\]]*=' /path/to/file |egrep -v '^#' |cut -d'=' -f1 |awk '{print $1}'
A
B
DEF
GHI1
JKL[1]
JKL['a']
JKL["b"]
for VAR in $(egrep '[a-zA-Z0-9"'\''\[\]]*=' /path/to/file |egrep -v '^#' |cut -d'=' -f1 |awk '{print $1}'); do
  eval echo "\$${VAR}"
done

命令说明:

  • 第一个egrep搜索包含任何数字以及小写(
    a-z
    )和/或大写(
    a-z
    )字母和/或方括号(
    \[\]
    )和/或单(
    '\'
    )和/或双(
    )引号后跟
    =/code>)的行
  • 第二个EGRP不包括以
    #
    开头的行,因为这些行通常被解释为注释,不会生成或设置变量
  • “剪切”命令会剪切从
    =
    到行尾的所有内容
  • awk命令打印第一次出现的空格或制表符以外的内容,因此有效地减少了变量名称前面的空白

  • 命令的输出可以在循环中使用,或者类似于以下内容:

    egrep '[a-zA-Z0-9"'\''\[\]]*=' /path/to/file |egrep -v '^#' |cut -d'=' -f1 |awk '{print $1}'
    
    A
    B
    DEF
    GHI1
    JKL[1]
    JKL['a']
    JKL["b"]
    
    for VAR in $(egrep '[a-zA-Z0-9"'\''\[\]]*=' /path/to/file |egrep -v '^#' |cut -d'=' -f1 |awk '{print $1}'); do
      eval echo "\$${VAR}"
    done
    

    这是使用awk的一种方法:

    egrep "*=" file |awk 'BEGIN{FS="="}{print $1}'|grep -v "#"|column -t
    
    说明:

    因为变量将有“=”用于赋值,所以使用它作为模式grep文件中的“*=”。完成后,我使用awk将字段分隔符声明为“=”,并使用$1打印出它之前的任何内容。Column-t只是用于将输出向左对齐


    希望有帮助。

    直接从文件中获取变量怎么样

    VARLIST=$(cut -d= -f1 file_with_variables)
    

    我倾向于建议在文档中使用易于解析的注释格式(如doxygen、javadoc和衍生工具)。您可以始终比较配置文件源前后的
    declare
    /
    set
    输出?=),或者,如果配置文件对于该函数是唯一的,则直接创建数组。如果它对于该函数不是唯一的,则您需要某种方法仅使用正确的变量,因此只需编写一个“collect\u args”“使用函数期望的变量名等的函数。谢谢@EtanReisner我认为您的建议可能不得不这样做,因为除了解析您可能想要查看的实际文件之外,我似乎找不到更好的解决方案。它可能对你有用。(我什么都不知道,我只是把它放在一张账单上看了一会儿。)你介意回答这个问题吗?您是否需要进一步的帮助,或者它可能不适合您的需要?不过,我通常只使用大写字母和数字作为变量名,以保持代码的可读性。:)非常感谢。我将尽快对此进行研究。grep-v“#”用于省略已注释的变量。如果希望打印出已注释的变量,则可以忽略此选项