Shell 使用replace搜索多个字符串以重新生成.config文件
我试图从运行在buildroot系统生成的操作系统(即OpenWRT)上的工作系统中重新生成buildroot系统的.config文件。例如,我有一个Seagate GoFLEX Home单元运行在自建的OpenWRT操作系统上,我已经丢失了它的原始.config文件。当然,我可以通过运行makemenuconfig并开始选择所有包来重新生成.config文件。但是,这个过程非常乏味。因此,我提出了以下过程来重新生成.config文件Shell 使用replace搜索多个字符串以重新生成.config文件,shell,awk,sed,Shell,Awk,Sed,我试图从运行在buildroot系统生成的操作系统(即OpenWRT)上的工作系统中重新生成buildroot系统的.config文件。例如,我有一个Seagate GoFLEX Home单元运行在自建的OpenWRT操作系统上,我已经丢失了它的原始.config文件。当然,我可以通过运行makemenuconfig并开始选择所有包来重新生成.config文件。但是,这个过程非常乏味。因此,我提出了以下过程来重新生成.config文件 登录我的Seagate GoFLEX Home unit并执
ac-power-control-by-USB-hub - 0.0.1-1
ahcpd - 0.53-2
alsa-lib - 1.0.28-1
alsa-lib-dev - 1.0.28-1
...
ac-power-control-by-USB-hub
ahcpd
alsa-lib
alsa-lib-dev
...
# CONFIG_PACKAGE_ac-power-control-by-USB-hub is not set
# CONFIG_PACKAGE_ahcpd is not set
# CONFIG_PACKAGE_alsa-lib is not set
# CONFIG_PACKAGE_alsa-lib-dev is not set
# CONFIG_PACKAGE_amrnb is not set
...
经过awk处理后,如下所示:
ac-power-control-by-USB-hub - 0.0.1-1
ahcpd - 0.53-2
alsa-lib - 1.0.28-1
alsa-lib-dev - 1.0.28-1
...
ac-power-control-by-USB-hub
ahcpd
alsa-lib
alsa-lib-dev
...
# CONFIG_PACKAGE_ac-power-control-by-USB-hub is not set
# CONFIG_PACKAGE_ahcpd is not set
# CONFIG_PACKAGE_alsa-lib is not set
# CONFIG_PACKAGE_alsa-lib-dev is not set
# CONFIG_PACKAGE_amrnb is not set
...
.config文件的示例如下所示:
ac-power-control-by-USB-hub - 0.0.1-1
ahcpd - 0.53-2
alsa-lib - 1.0.28-1
alsa-lib-dev - 1.0.28-1
...
ac-power-control-by-USB-hub
ahcpd
alsa-lib
alsa-lib-dev
...
# CONFIG_PACKAGE_ac-power-control-by-USB-hub is not set
# CONFIG_PACKAGE_ahcpd is not set
# CONFIG_PACKAGE_alsa-lib is not set
# CONFIG_PACKAGE_alsa-lib-dev is not set
# CONFIG_PACKAGE_amrnb is not set
...
#!/bin/sh
LIST="/tmp/opkg-list-installed.txt"
FCFG="/tmp/.config"
echo -n "Processing "
for f in $(cat $LIST)
do
echo -n "."
sed -i "s|# CONFIG_PACKAGE_$f is not set|CONFIG_PACKAGE_$f=y|g" $FCFG
done
echo
echo "done"
CONFIG_PACKAGE_ac-power-control-by-USB-hub=y
CONFIG_PACKAGE_ahcpd=y
CONFIG_PACKAGE_alsa-lib=y
CONFIG_PACKAGE_alsa-lib-dev=y
# CONFIG_PACKAGE_amrnb is not set
...
EDIT:我用一些示例数据更新了上述内容。使用
for
循环和cat
是shell中的反模式。您应该在读取循环时使用。但是,代码运行缓慢的主要原因似乎是您正在调用sed
,并对$LIST
的每个单词运行一次整个文件$FCFG
。我建议采用完全不同的方法,使用awk
而不是循环:
awk 'NR==FNR{a[$0];next}{for(i in a)sub("# CONFIG_PACKAGE_" i " is not set", "CONFIG_PACKAGE_" i "=y")}1' "$LIST" "$FCFG"
第一个块将$LIST
读入内存,第二个块执行与使用sed
执行的替换相同的替换
我假设您的文件$LIST
每行包含一个单词
要“就地”执行编辑,可以使用
awk '...' "$LIST" "$FCFG" > tmp && mv tmp "$FCFG"
只需稍加修改(将第一块中的$0
更改为$1
),即可跳过一步,从原始输入文件转到所需输出:
$ cat list
ac-power-control-by-USB-hub - 0.0.1-1
ahcpd - 0.53-2
alsa-lib - 1.0.28-1
alsa-lib-dev - 1.0.28-1
$ cat config
# CONFIG_PACKAGE_ac-power-control-by-USB-hub is not set
# CONFIG_PACKAGE_ahcpd is not set
# CONFIG_PACKAGE_alsa-lib is not set
# CONFIG_PACKAGE_alsa-lib-dev is not set
# CONFIG_PACKAGE_amrnb is not set
$ awk 'NR==FNR{a[$1];next}{for(i in a)sub("# CONFIG_PACKAGE_" i " is not set", "CONFIG_PACKAGE_" i "=y")}1' list config
CONFIG_PACKAGE_ac-power-control-by-USB-hub=y
CONFIG_PACKAGE_ahcpd=y
CONFIG_PACKAGE_alsa-lib=y
CONFIG_PACKAGE_alsa-lib-dev=y
# CONFIG_PACKAGE_amrnb is not set
Sed在一个可以是多行的“程序”上工作。
将编辑内容汇编到文件中:
for f in $(</tmp/opkg-list-installed.txt)
do echo "s@# ... $f@...$f=y@g" ; done > /tmp/edits
sed -i -f /tmp/edits $FCFG
以美元为单位的f的(/tmp/edits)
sed-i-f/tmp/edits$FCFG
$LIST
看起来像什么?你能发布一个示例吗?很抱歉丢失了数据。我已经编辑了原始帖子以包含一些示例数据。我对awk不太熟悉,但它似乎不起作用。我真的不知道会发生什么,但脚本似乎从未触及opkg-LIST-installed.txt和.config文件(两个文件的时间戳和大小都保持不变)。我甚至试图用$I替换I,但不幸的是,结果是相同的问题。缺少一个{print}
块,这意味着不会打印任何内容。我在一行的末尾添加了一个1
,这是{print}的常用缩写
。它现在应该打印到标准输出,然后如果您对输出满意,可以使用第二个代码块中的重定向来覆盖原始文件。@user3767809我添加了一个演示,演示如何从原始列表转到所需的输出。这很管用。如果您从我的原始帖子中注意到,我使用已安装的opkg列表| awk'{print$1}“>/tmp/opkg-list-installed.txt生成列表。由于我对awk不太熟悉,您认为您可以帮助我将其与您的单行awk组合成一个单行代码吗?@user3767809上一个示例就是这样做的,因为它使用$1
保存数组a
中的第一个字段。