Tem problemas com o comando sed no Linux [closed]

1

Estou enfrentando algum problema estranho com o comando sed ao substituir o conteúdo em um arquivo. Eu criei um arquivo fictício com poucas linhas e tentei executar meu script. Funcionou.

O mesmo script não substitui a string quando eu uso o arquivo lvm.conf .

A tarefa é anexar o caminho do disco ao arquivo global_filter in lvm.conf .

A entrada será /dev/sdb1 e eu tenho que adicionar o mesmo ao global_filter global_filter = ["a|^/dev/sda2$|", "r/.*/"]

Meu script é o seguinte:

#!/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

Eu usei várias instruções echo para ver a saída, vou removê-las assim que o script estiver funcionando bem.

A entrada é "/dev/sda2"

A saída esperada no arquivo lvm.conf é:

global_filter = ["a|^/dev/sda1$|","a|^/dev/sda2$|","r/.*/"]

Haverá uma entrada global_filter no arquivo lvm.conf . Na execução deste script, esse filtro deve ser atualizado.

Como esse arquivo é enorme, eu copiei a seção onde global_filter está presente em um arquivo separado e trabalhando no mesmo.

arquivo 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'.

Na execução do script, o arquivo deve ser alterado conforme abaixo

# 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'.

A entrada para o script deve ser estritamente do tipo /dev/sda2 .

    
por niranuv 10.02.2017 / 13:23

1 resposta

0

Eu acredito que isso faz o que você precisa:

addition=', "a|^/dev/sda2$|"'
expression='/global_filter/ s@(, "r)@'"$addition"\1'@'
sed -r -i.orig "${expression}" /etc/lvm.conf

O truque aqui é usar a correspondência de padrão de sed para corresponder à linha com / global_filter / e, em seguida, usar a pesquisa / substituição, para substituir apenas o bit em torno da vírgula:    "r

com sua nova adição.

O sinalizador '-r' é necessário aqui para o sed, a fim de capturar a parte ',' r 'com os parênteses' (padrão) ', para que você possa inseri-lo novamente após a adição, usando a referência anterior " \ 1 "

Ou mais simples de entender, sem as correspondências -r e '()':

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"

Eu assumi que 'dev / dasda2' em seu arquivo de entrada de exemplo não é a entrada verdadeira, mas foi deixado lá de uma edição com falha.

    
por 12.02.2017 / 06:07