sed를 사용하여 동시에 제거 및 추가

sed를 사용하여 동시에 제거 및 추가

스크립트에 변경하고 싶은 변수가 있습니다.

read -p "Enter the name of city: " city
if [[ $city =~ Liverpool ]]; then
    sed -i -e "/\$type\_of\_city =/ s/= .*/= ${city}/" /cities  
    echo -e "Liverpool: `grep '$name_of_city' cities"
fi

#도시 파일에는 삭제하고 싶은 변수가 있습니다 :

#$type_of_city = something

something그래서 위의 코드와 실제로 작동 하도록 두 가지를 모두 변경하고 싶지만 Liverpool플래그를 제거하는 방법을 모르겠습니다 #.

이제 알겠습니다 #$type_of_city = Liverpool. 하지만 보고 싶습니다 $type_of_city = Liverpool.

답변1

코드 블록을 조금 수정하고,

read -p "Enter the name of city: " city
if [ "$city" = 'Liverpool' ]
then
    sed -Ei 's/^#* *(\$type_of_city) *= *.*/\1 = '"$city"'/' cities  
    printf "%s: %s\n" "$city" "$(grep -F "$city" cities)"
fi

여기서는 확장된 RE와 행을 일치시킵니다 ^#* *(\$type_of_city) *= *.*. 세분화하면 다음과 같습니다.

  • ^- 줄의 시작
  • #*- 0개 이상의 #문자
  • *- 0개 이상의 공백
  • ()- 둘러싸는 블록과 일치하며 나중에 다음과 같이 사용됩니다.\1
  • \$type_of_city- 리터럴 문자열 $type_of_city( \$줄 끝과의 잘못된 일치를 방지하기 위해 이스케이프됨)
  • *- 0개 이상의 공백
  • =- 텍스트 문자
  • *- 0개 이상의 공백
  • .*- 0개 이상의 임의 문자

일치가 성공하면 행을 다음과 같이 다시 작성합니다. \1 = $city여기서 는 \1괄호 안의 (... )ERE 값 이고 $city는 변수의 값입니다.

변수 값을 대체 문자열 $city에 직접 입력하므로 와 같은 문자나 시퀀스 가 ​​포함된 경우 기껏해야 예상치 못한 결과가 생성되거나 오류가 발생할 수도 있습니다. 현재 코드에서는 입력 값이 이어야 하는 절로 보호 되지만 해당 절을 제거하거나 너무 많이 완화하면 이 문제가 발생할 수 있습니다.sed/\1sedifLiverpool

답변2

귀하의 경우 전체 줄을 로 바꾸겠습니다 sed. 여기서 는 #줄 시작 후의 선택적 문자에 고정됩니다.

sed "s/^#\{0,1\}\$type_of_city =.*/type_of_city = $city/" /cities

이것은 대체됩니다

  • #줄 시작( ) 바로 뒤에 0 또는 1회 표시되고 ^그 뒤에
  • 리터럴 문자열 $type_of_city =다음에
  • 줄 끝까지의 모든 텍스트

가 있고 $type_of_city =그 뒤에 내용이 옵니다.껍데기바꾸다 $city.

검색 패턴이 일치하는 경우에만 교체가 수행되므로 사용하는 주소 지정자는 필요하지 않습니다.

노트사용자 입력을 가져 오므로 $city입력을 사용하기 전에 유효성을 검사/검증해야 합니다. 그렇지 않으면 스크립트가 열립니다.코드 삽입 취약점사용자가 sed입력에 명령 구문을 포함하는 경우.

Stéphane Chazelas가 주석에서 지적했듯이 코드에 값을 삽입하는 대신 perl환경을 통해 또는 매개변수로 값이 전달되는 위치를 사용하여 이를 방지할 수 있습니다.sed$citysed

관련 정보