所以我有一个如下所示的文件
#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
最后删除所有四行的注释