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는 역참조 "\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"는 실제 입력이 아니지만 편집 실패로 인해 남아 있다고 가정합니다.