我正在尝试修改一些包含预定义编译器标志的环境变量。为此,我尝试使用 bash 循环遍历所有以“env”列出的环境变量。
for i in $(env | grep ipo | awk 'BEGIN {FS="="} ; { print $1 } ' )
do echo $(sed -e "s/-ipo/ / ; s/-axAVX/ /" <<< $i)
done
这是行不通的,因为循环变量 $i 只包含存储为字符串的环境变量的名称。我尝试搜索一种将字符串转换为变量的方法,但事情开始变得不必要的复杂。基本问题是如何正确地将环境变量本身提供给 sed。
欢迎任何关于如何正确修改我的脚本的想法。
谢谢, 亚历克斯
最佳答案
第一部分
您解析 env
的方式是错误的。只要您有空格或通配符,它就会中断。而是使用这个:
while IFS= read -r line; do
# do stuff with variable line
done < <(env)
要了解您的解决方案失败的原因,请执行以下操作:
for i in $(env); do
echo "$i"
done
您很可能会看到 env
的输出有所不同。
现在,当您的变量中有换行符时,我提供的 while
方法也会中断。
很可能您的 env
版本具有标志 -0
或 --null
。使用它是 100% 安全的:
while IFS= read -r -d '' line; do
# do stuff with variable line
done < <(env --null)
第二部分
当你读完你的行后,你想把它分成一个键和一个值。不要为此使用 awk。使用 Bash:
key=${line%%=*}
value=${line#*=}
看:
while IFS= read -r -d '' line; do
key=${line%%=*}
value=${line#*=}
echo "key: $key"
echo "value: $value"
done < <(env --null)
第三部分
现在我明白您只想对包含字符串 ipo
的变量进行操作,并且对于这些您想要用空格替换字符串 -ipo
和 -axAVX
。所以:
while IFS= read -r -d '' line; do
key=${line%%=*}
value=${line#*=}
[[ $value = *ipo* ]] || continue
value=${value/-ipo/ }
value=${value/-axAVX/ }
echo "key: $key"
echo "new value: $value"
done < <(env --null)
第四部分
您想用这个新值替换变量。您可以为此使用declare
。 (您不需要内置的 export
,因为您的变量已经被标记为已导出):
while IFS= read -r -d '' line; do
key=${line%%=*}
value=${line#*=}
[[ $value = *ipo* ]] || continue
value=${value/-ipo/ }
value=${value/-axAVX/ }
declare "$key=$value"
done < <(env --null)
第五部分
最后,您将尝试将其放入脚本中,您将意识到它不起作用:那是因为脚本是在子进程中执行的,而子进程中所做的每项更改都不会被子进程看到父进程。所以你会想要采购它!要获取文件 file
,请使用:
. file
(是的,一个点、一个空格和文件名)。
关于regex - 使用 sed 修改 bash 变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24179844/