我有一个好奇的问题,我无法弄清楚......
假设我们有一个变量:
_file="/var/log/messages"
并且文件也包含这个块:
/var/log/secure /var/log/messages /var/log/cron /var/log/maillog {
compress
monthly
rotate 6
create 600
sharedscripts
postrotate
/bin/kill -HUP `cat /var/run/*syslog*.pid 2> /dev/null` 2> /dev/null || true
endscript
}
我需要一个 sed 命令来选择这个以 $_file 开头并以 } 结尾的特定块,然后在其中执行某些操作......比如说从中删除 $_file。
第一个问题是它的路径,所以我们需要在 sed 中更改分隔符
sed -e "s|$_file[[:space:]]||" tests_file.txt
上面可以工作,但我需要指定块,通常它应该看起来像:
sed -e "|$_file|,|\}|{s|$_file[[:space:]]||}"
但总是失败:
sed: -e expression #1, char 1: unknown command: `|'
知道发生什么事了吗?
答案1
你s
可以直接选择分隔符。它可以是
s/a/b/
s|a|b|
sxaxbx
但所选的字符必须是单字节字符。
当将正则表达式指定为地址时,它就不那么简单了:
/regex/
\cregexc
其中c
是任意单字节字符。这意味着如果您选择|
,则需要在 之前对其进行转义regex
,但无需在 之后对其进行转义。
sed -e "\|$_file|,\|\}|{s|$_file[[:space:]]||}" tests_file.txt
# ^ here ^
sed
它可以与我的 Debian 9 中的GNU 配合使用。
不过你的例子不太恰当。带有 的行$_file
总是位于一个块内,s
因此总是影响它。这是因为如果你试图把它放在$_file
块外面,它将启动一个新的堵塞。
更具教育意义的例子:
sed -e "\|$_file|,\|\}| s|a|X|g" tests_file.txt
这会将块内的每个 更改为a
。X
如果您将包含 的行a
放在任何块之外,则不会受到影响。(请注意,我删除了和{
。在这个简单的情况下,它们不是必需的。)}
s
答案2
_file 变量中的 '/' 使 sed 感到困惑,因为它使用 '/' 作为地址的分隔符以及替代分隔符。
您需要更改分隔符(例如更改为|
),从而必须对每个地址的第一个分隔符进行转义(如下所示\|
):
sed -e "\|.*$_file .*{$|,\|^}$|s|$_file ||" test_file.txt