在文件末尾插入和更新代码块

在文件末尾插入和更新代码块

所以我有一个如下所示的文件

#ifndef CONFIG_DHCP_H
#define CONFIG_DHCP_H

FILE_LICENCE(GPL2_OR_LATER_OR_UBDL);

#include <config/defaults.h>

#define DHCP_DISC_START_TIMEOUT_SEC 1
#define DHCP_DISC_END_TIMEOUT_SEC 10
//#define DHCP_DISC_START_TIMEOUT_SEC   4   /* as per PXE spec */
//#define DHCP_DISC_END_TIMEOUT_SEC 32  /* as per PXE spec */

/*
 * .
 * .
 * .
 */

#define PXEBS_MAX_TIMEOUT_SEC 3
//#define PXEBS_MAX_TIMEOUT_SEC     7   /* as per PXE spec */

#include <config/local/dhcp.h>

#endif /* CONFIG_DHCP_H */

正如 所示,它要长得多,...但我突出显示了相关部分。我需要将其更改为以下内容

#ifndef CONFIG_DHCP_H
#define CONFIG_DHCP_H

FILE_LICENCE(GPL2_OR_LATER_OR_UBDL);

#include <config/defaults.h>

#define DHCP_DISC_START_TIMEOUT_SEC 1
#define DHCP_DISC_END_TIMEOUT_SEC 10
//#define DHCP_DISC_START_TIMEOUT_SEC   4   /* as per PXE spec */
//#define DHCP_DISC_END_TIMEOUT_SEC 32  /* as per PXE spec */

/*
 * .
 * .
 * .
 */

#define PXEBS_MAX_TIMEOUT_SEC 3
//#define PXEBS_MAX_TIMEOUT_SEC     7   /* as per PXE spec */

#include <config/local/dhcp.h>

#undef DHCP_DISC_START_TIMEOUT_SEC
#define DHCP_DISC_START_TIMEOUT_SEC 4
#undef DHCP_DISC_END_TIMEOUT_SEC
#define DHCP_DISC_END_TIMEOUT_SEC 32

#endif /* CONFIG_DHCP_H */

换句话说,在底部插入四行。但请注意,这些行也出现在文件的前面,并且不得触及。如果这些行存在,人们应该能够更新它们的值。

我对顶部测试文件的尝试保存dhcp.h如下

#!/bin/bash

dhcp="${1:-dhcp.h}"

read -r -d '' dhcp_regex_timeout <<'EOM'
#undef *DHCP_DISC_START_TIMEOUT_SEC
#define *DHCP_DISC_START_TIMEOUT_SEC *\d+
#undef *DHCP_DISC_END_TIMEOUT_SEC
#define *DHCP_DISC_END_TIMEOUT_SEC *\d+
EOM

read -r -d '' dhcp_correct_timeout <<EOM
#undef DHCP_DISC_START_TIMEOUT_SEC
#define DHCP_DISC_START_TIMEOUT_SEC ${2:-4}
#undef DHCP_DISC_END_TIMEOUT_SEC
#define DHCP_DISC_END_TIMEOUT_SEC ${3:-32}
EOM

echo "${dhcp_correct_timeout}"

if grep -Pazoq "${dhcp_regex_timeout}\n+#endif" "${dhcp}"; then
  # The block is present at the end of the file, time to update it
  sed "s/${dhcp_regex_timeout}/${dhcp_correct_timeout}/"
else
  # The block is NOT present at the end of the file, time to insert it
  sed -E "s/\n*\(#endif .*\)/${dhcp_correct_timeout}\n\n\1/"
fi

有什么建议么?上面的代码只是一个草图,不起作用,但它显示了我想要做的事情。我愿意接受其他解决方案,例如awk这是否会让事情变得更容易=)

答案1

如果代码尚不存在,您可以使用 的保留空间来sed收集带注释的定义并将它们放在末尾而不带注释,并首先取消定义它们:

sed '\|//#define DHCP_DISC_.*_TIMEOUT_SEC|H;\|include <config/local/dhcp.h>|{G;s/define/undef/g;s/ [0-9][[:print:]]*//g;G;s|//||g;}'

所以你有了这个一次性sed命令,不需要所有其他代码。详细地:

  • \|//#define DHCP_DISC_.*_TIMEOUT_SEC|H将把这些行附加到保留空间以供以后使用
  • \|include <config/local/dhcp.h>|匹配应在其后放置新行的行。所有进一步的命令仅针对该行执行
  • G将保留空间(保存的行和空行,这将帮助我们很好地分离代码)附加到模式空间
  • s/define/undef/g是取消定义而不是定义
  • s/ [0-9][[:print:]]*//g将删除 undefine 的定义(和注释)
  • G再次添加行,这次是为了重新定义
  • s|//||g最后删除所有四行的注释

相关内容