Linuxでsedコマンドを使用する際に問題があります。

Linuxでsedコマンドを使用する際に問題があります。

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_filterlvm.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」は実際の入力ではありませんが、編集に失敗したため残っているとします。

関連情報