替换文件中的环境变量:awk 还是 sed?
我有一个在 shell 脚本中获取的环境变量文件,例如:
# This is a comment
ONE=1
TWO=2
THREE=THREE
# End
在我的脚本中,我将该文件(假设它称为“./vars”)获取到当前环境中,并根据以下内容更改(部分)变量:用户输入。例如:
#!/bin/sh
# Read variables
source ./vars
# Change a variable
THREE=3
# Write variables back to the file??
awk 'BEGIN{FS="="}{print $1=$$1}' <./vars >./vars
如您所见,我一直在尝试使用 awk 来写回变量,sed 也是如此。没有成功。脚本的最后一行失败。有没有办法用 awk 或 sed 来做到这一点(最好保留注释,甚至带有“=”字符的注释)?或者我应该将“读取”与 while 循环中的字符串切割或其他魔法结合起来?如果可能的话,我想避免使用 perl/python,而只使用 Busybox 中提供的工具。非常感谢。
编辑:也许一个用例可以清楚地说明我的问题是什么。我保留一个由 shell 环境变量声明组成的配置文件:
# File: network.config
NETWORK_TYPE=wired
NETWORK_ADDRESS_RESOLUTION=dhcp
NETWORK_ADDRESS=
NETWORK_ADDRESS_MASK=
我还有一个名为“setup-network.sh”的脚本:
#!/bin/sh
# File: setup-network.sh
# Read configuration
source network.config
# Setup network
NETWORK_DEVICE=none
if [ "$NETWORK_TYPE" == "wired" ]; then
NETWORK_DEVICE=eth0
fi
if [ "$NETWORK_TYPE" == "wireless" ]; then
NETWORK_DEVICE=wlan0
fi
ifconfig -i $NETWORK_DEVICE ...etc
我还有一个名为“configure-network.sh”的脚本:
#!/bin/sh
# File: configure-network.sh
# Read configuration
source network.config
echo "Enter the network connection type:"
echo " 1. Wired network"
echo " 2. Wireless network"
read -p "Type:" -n1 TYPE
if [ "$TYPE" == "1" ]; then
# Update environment variable
NETWORK_TYPE=wired
elif [ "$TYPE" == "2" ]; then
# Update environment variable
NETWORK_TYPE=wireless
fi
# Rewrite configuration file, substituting the updated value
# of NETWORK_TYPE (and any other updated variables already existing
# in the network.config file), so that later invocations of
# 'setup-network.sh' read the updated configuration.
# TODO
如何重写配置文件,仅更新配置文件中已经存在的变量,最好保留注释和空行完好无损?希望这能让事情澄清一点。再次感谢。
I have a file of environment variables that I source in shell scripts, for example:
# This is a comment
ONE=1
TWO=2
THREE=THREE
# End
In my scripts, I source this file (assume it's called './vars') into the current environment, and change (some of) the variables based on user input. For example:
#!/bin/sh
# Read variables
source ./vars
# Change a variable
THREE=3
# Write variables back to the file??
awk 'BEGIN{FS="="}{print $1=$1}' <./vars >./vars
As you can see, I've been experimenting with awk for writing the variables back, sed too. Without success. The last line of the script fails. Is there a way to do this with awk or sed (preferably preserving comments, even comments with the '=' character)? Or should I combine 'read' with string cutting in a while loop or some other magic? If possible, I'd like to avoid perl/python and just use the tools available in Busybox. Many thanks.
Edit: perhaps a use case might make clear what my problem is. I keep a configuration file consisting of shell environment variable declarations:
# File: network.config
NETWORK_TYPE=wired
NETWORK_ADDRESS_RESOLUTION=dhcp
NETWORK_ADDRESS=
NETWORK_ADDRESS_MASK=
I also have a script called 'setup-network.sh':
#!/bin/sh
# File: setup-network.sh
# Read configuration
source network.config
# Setup network
NETWORK_DEVICE=none
if [ "$NETWORK_TYPE" == "wired" ]; then
NETWORK_DEVICE=eth0
fi
if [ "$NETWORK_TYPE" == "wireless" ]; then
NETWORK_DEVICE=wlan0
fi
ifconfig -i $NETWORK_DEVICE ...etc
I also have a script called 'configure-network.sh':
#!/bin/sh
# File: configure-network.sh
# Read configuration
source network.config
echo "Enter the network connection type:"
echo " 1. Wired network"
echo " 2. Wireless network"
read -p "Type:" -n1 TYPE
if [ "$TYPE" == "1" ]; then
# Update environment variable
NETWORK_TYPE=wired
elif [ "$TYPE" == "2" ]; then
# Update environment variable
NETWORK_TYPE=wireless
fi
# Rewrite configuration file, substituting the updated value
# of NETWORK_TYPE (and any other updated variables already existing
# in the network.config file), so that later invocations of
# 'setup-network.sh' read the updated configuration.
# TODO
How do I rewrite the configuration file, updating only the variables already existing in the configuration file, preferably leaving comments and empty lines intact? Hope this clears things up a little. Thanks again.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您不能使用 awk 并从同一文件中读取和写入(这是您问题的一部分)。
我更喜欢在重写之前重命名该文件(但您也可以保存到 tmp,然后也重命名)。
如果您的 env 文件变大,您会发现它会根据操作系统的缓冲区大小被截断。
另外,不要忘记 gawk(大多数 Linux 安装上的 std)有一个内置数组 ENVIRON。您可以从中创建您想要的内容
当然,您可以获得环境中的所有内容,因此可能比您想要的更多。但可能是一个更好的地方来开始你想要完成的事情。
编辑
最具体的是
编辑2
我认为您的 var=values 可能需要
export
-ed,以便它们对 awk ENVIRON 数组可见。AND
打印 PATH 的现有值。
我希望这有帮助。
PS,由于您似乎是新用户,如果您得到的答案对您有帮助,请记住将其标记为已接受,和/或给它 +(或 -)作为有用的答案。
You can't use awk and read and write from the same file (is part of your problem).
I prefer to rename the file before I rewrite (but you can save to a tmp and then rename too).
If your env file gets bigger, you'll see that is is getting truncated at the buffer size of your OS.
Also, don't forget that gawk (the std on most Linux installations) has a built in array ENVIRON. You can create what you want from that
Of course you get everything in your environment, so maybe more than you want. But probably a better place to start with what you are trying to accomplish.
Edit
Most specifically
Edit 2
I think your var=values might need to be
export
-ed so they are visible to the awk ENVIRON array.AND
prints the existing value of PATH.
I hope this helps.
P.S. as you appear to be a new user, if you get an answer that helps you please remember to mark it as accepted, and/or give it a + (or -) as a useful answer.
我不完全知道你想做什么,但如果你想改变变量 THREE 的值,
I don't exactly know what you are trying to do, but if you are trying to change the value of variable THREE ,
您可以仅使用 bash 来执行此操作:
像使用临时文件一样使用它
来尽可能长时间地维护配置文件的存在。
You can do this in just with bash:
Use it like
I use a temp file to maintain the existance of the config file for as long as possible.