打印所有环境变量但跳过多行变量

Print all environment variables but skipping multiline variables

我想打印除某些变量之外的所有环境变量。

于是在Whosebug上找到了解决方案:Bash: loop through variables containing pattern in name

while IFS='=' read -r name value; do
    if [ ! "$name" = "SOMEVAR" -a ! "$name" = "SOMEOTHERVAR" ]; then
        echo "$name=$value"
    fi
done < <(env)

但是,如果我的环境变量包含换行符,这将不起作用,例如:

export SOMEVAR="some
text with
newlines"

使用上述解决方案,它将打印:

text with=
newlines=
PWD=/home/...
...

我还尝试使用以 null 结尾的字符串和多行匹配 sed:

env -0 | sed -e '{N; s@SOMEVAR.*\x0@@ ; D}' | tr '[=13=]' '\n'

但这会切断输出并且总是首先打印具有多行内容的变量的最后一行:

newlines
PWD=/home/...
...

有没有办法在打印时跳过多行环境变量?

您几乎已经掌握了,您只需要使用读取命令和空分隔符遍历 env -0 的输出,并使用正则表达式运算符排除变量

while read -r -d '' line; do 
    [[ ! $line =~ ^(SOMEVAR|SOMEOTHERVAR)= ]] && printf '%s\n' "$line" 
done < <(env -0)

d ''read 命令表示在空分隔符上分隔输入。 while 循环一直运行到解析完最后一个定界行为止。

此外,这只是 打印 所有变量,不包括您要避免的变量。为了进一步处理每一行,您可以解析出 $line 变量以拆分 key/value 对并使用它因此。

或者,如果您的目的是识别包含 任何 变量的 multi-line 字符串,您可以使用正则表达式 as

排除该变量
[[ ! $line =~ $'\n' ]] 

您可以使用 bash 内置 compgen ,当与 -v 选项一起使用时输出所有环境变量名称,因此:

compgen -v # prints all variable names

现在您可以轻松地在循环中使用它来排除不需要的名称并打印其余部分:

while read var; do
   echo "$var=${!var}"
done < <(compgen -v | grep -vxFE '(SOMEVAR|SOMEOTHERVAR)')