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/行をマッチングし、検索/置換を使用してコンマの周りのビットのみを置き換えることです。
あなたの新しい追加で。
sed は、逆参照 "\1" を使用して追加して再挿入できるように、 '(パターン)' 角かっこがある ' , 'r ' 部分をキャプチャするためにここに '-r' フラグが必要です。
または -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」は実際の入力ではありませんが、編集に失敗したため残っているとします。