使用replace搜索多个字符串以重新生成.config文件

时间:2015-03-19 14:07:48

标签: shell awk sed

我正在尝试从在buildroot系统(即OpenWRT)生成的操作系统上运行的工作系统中重新生成buildroot系统的.config文件。例如,我有一个在自建的OpenWRT操作系统上运行的Seagate GoFLEX Home设备,我已经丢失了原来的.config文件。当然,我可以通过运行 make menuconfig 重新生成.config文件,然后开始选择所有包。但是,这个过程非常繁琐。所以,我想出了以下过程来重新生成.config文件。

  1. 登录我的Seagate GoFLEX Home设备并执行 opkg list-installed | awk'{print $ 1}'> /tmp/opkg-list-installed.txt 生成已安装软件包的列表,以显示已安装的软件包。

    awk 处理之前 opkg list-installed 转储的摘录如下所示:

    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
    ...
    

    awk 处理后,如下所示:

    ac-power-control-by-USB-hub
    ahcpd
    alsa-lib
    alsa-lib-dev
    ...
    

    并且.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
    ...
    
  2. /tmp/opkg-list-installed.txt 传输到buildroot系统所在的主机。

  3. 使用 sed 处理生成的列表文件( /tmp/opkg-list-installed.txt )以刷新.config文件,如下所示

    #!/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"
    
  4. 由于某些软件包包含子软件包和/或子模块,因此在运行 make menuconfig 以重新刷新(重新生成).config之后,此过程才会完成。文件。

    以下是我希望上面的摘录.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
    ...
    
  5. 在上面的步骤#3中,AMD64计算机重新生成.config文件大约需要100秒。对我来说,这个过程有点慢,我想知道是否有人在这里知道从已安装的软件包列表中重新生成.config文件的更好方法。

    编辑:我使用一些示例数据更新了上述内容。

2 个答案:

答案 0 :(得分:3)

for循环使用cat是shell中的反模式。您应该使用while read循环代替。但是,看起来您的代码速度慢的主要原因是您要调用sed并为$FCFG的每个单词运行整个文件$LIST一次。我会建议使用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

答案 1 :(得分:0)

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