sed
我在替换文件中的内容时遇到一些奇怪的命令问题。我创建了一个只有几行的虚拟文件并尝试执行我的脚本。有效。
当我使用该文件时,相同的脚本无法替换字符串lvm.conf
。
任务是将磁盘路径附加到文件global_filter
中lvm.conf
。
输入将是/dev/sdb1
,我必须将相同的内容添加到global_filter
global_filter = ["a|^/dev/sda2$|", "r/.*/"]
我的脚本如下:
#!/bin/sh
function addToFilter(){
app_lvm_conf="/etc/lvm/lvm.conf"
line=$(sed -n '/global_filter =/p' $app_lvm_conf)
echo $line
exstngfltr=$(echo $line | cut -d "[" -f2 | cut -d "]" -f1)
echo $exstngfltr
IFS=', ' read -r -a array <<< "$exstngfltr"
echo ${array[@]}
numOfEntries=${#array[@]}
echo $numOfEntries
value=$(IFS=,; echo "${array[*]}")
echo $value
temp="${array[numOfEntries-1]}"
echo $temp
ar=$1
echo $ar
a='"a|^'
b='$|"'
z=$a$1$b
echo $z
array[numOfEntries-1]=$z
array[numOfEntries]=$temp
newValue=$(IFS=,; echo "${array[*]}")
sed -i "s@$value@$newValue@g" $app_lvm_conf
}
addToFilter $1
我使用了多个 echo 语句来查看输出,一旦脚本正常工作,我将删除它们。
输入是"/dev/sda2"
文件中的预期输出lvm.conf
是:
global_filter = ["a|^/dev/sda1$|","a|^/dev/sda2$|","r/.*/"]
文件中将有一个global_filter
条目。lvm.conf
执行此脚本时,该过滤器应该得到更新。
由于该文件很大,我已将global_filter
存在的部分复制粘贴到单独的文件中并进行相同的处理。
lvm.conf 文件
# Since "filter" is often overridden from command line, it is not suitable
# for system-wide device filtering (udev rules, lvmetad). To hide devices
# from LVM-specific udev processing and/or from lvmetad, you need to set
# global_filter. The syntax is the same as for normal "filter"
# above. Devices that fail the global_filter are not even opened by LVM.
global_filter = ["a|^/dev/dasda2$|", "r/.*/"]
# The results of the filtering are cached on disk to avoid
# rescanning dud devices (which can take a very long time).
# By default this cache is stored in the /etc/lvm/cache directory
# in a file called '.cache'.
执行脚本时,文件应更改如下
# Since "filter" is often overridden from command line, it is not suitable
# for system-wide device filtering (udev rules, lvmetad). To hide devices
# from LVM-specific udev processing and/or from lvmetad, you need to set
# global_filter. The syntax is the same as for normal "filter"
# above. Devices that fail the global_filter are not even opened by LVM.
global_filter = ["a|^/dev/sda1$|", "a|^/dev/sda2$|", "r/.*/"]
# The results of the filtering are cached on disk to avoid
# rescanning dud devices (which can take a very long time).
# By default this cache is stored in the /etc/lvm/cache directory
# in a file called '.cache'.
脚本的输入应严格属于 类型/dev/sda2
。
答案1
我相信这可以满足您的需要:
addition=', "a|^/dev/sda2$|"'
expression='/global_filter/ s@(, "r)@'"$addition"\\1'@'
sed -r -i.orig "${expression}" /etc/lvm.conf
这里的技巧是使用 sed 的模式匹配来匹配 /global_filter/ 的行,然后使用搜索/替换,仅替换逗号周围的位: , "r
与您的新添加。
sed 此处需要 '-r' 标志,以便捕获带有括号 '(pattern)' 的 ' , "r ' 部分,以便您可以在添加后使用反向引用 "\1" 重新插入它
或者,更容易理解,没有 -r 和 '()' 匹配:
addToFilter()
{
device="${1}"
addition='"a|^'"${device}"'$|"'
insert_before=', "r'
replacement=", ${addition}${insert_before}"
line_match="global_filter"
expression="/${line_match}/ s@${insert_before}@${replacement}@"
sed -i.orig -e "${expression}" /etc/lvm.conf
}
addToFilter "/dev/sda2"
我假设示例输入文件中的“dev/dasda2”不是真正的输入,而是因编辑失败而留在那里。