l0b*_*0b0 5 text-processing replace
我必须自动在配置文件中插入一行,但需要注意的是,如果页脚存在,它应该插入在多行页脚注释和任何前面的空行或纯空白行之前。也就是说,应该在最后一个配置行之后立即插入新行,从而与原始文件形成单行差异。在伪代码中:
配置行的扩展正则表达式: ^\s*[^[:space:]#]
任何常见的 *nix 工具,例如sed
, awk
,ed
或ex
都应该可以工作。
可能的解决方案及其问题:
tac
两次使其成为向前搜索问题而不是向后搜索问题。这意味着我必须将结果存储在一个临时文件中,然后替换原始文件,而不是在单个命令中执行此操作。sed -i
与逆转伎俩。这意味着将整个文件存储在内存中。ex -c '1' -c '?^\s*[^[:space:]#]?' -c $'a\nmy new line\n.' -c 'wq' /path
,我也了解将完整文件存储在内存中。有没有解决这两个问题的解决方案?
示例起始文件:
# Universe configuration
#
pi = 3 # A good #
e = mc**2 # To within a hair
[cut 200 trillion lines]
#
# END
#
Run Code Online (Sandbox Code Playgroud)
示例输入:
sol { mass = 42, start = 9.2 }
Run Code Online (Sandbox Code Playgroud)
预期输出:
# Universe configuration
#
pi = 3 # A good #
e = mc**2 # To within a hair
[cut 200 trillion lines]
sol { mass = 42, start = 9.2 }
#
# END
#
Run Code Online (Sandbox Code Playgroud)
你可以按照这些思路做一些事情:
file=/some/file
newtext='sol { mass = 42, start = 9.2 }'
tac -- "$file" |
NEWTEXT=$newtext awk -v size="$(wc -c < "$file")" '
$1 ~ /^[^#]/ {
system("dd bs=1 seek=" size - length(footer) " conv=notrunc if=/dev/null")
printf "%s\n%s", ENVIRON["NEWTEXT"], footer
exit
}
{footer=$0 "\n" footer}' 1<> "$file"
Run Code Online (Sandbox Code Playgroud)
这会就地覆盖文件并仅将页脚存储在内存中。它需要非标准的 GNUtac
命令。该文件必须是常规文本文件。