패턴을 변수로 교체

패턴을 변수로 교체

$new다른 변수에 사용하고 저장한 파일의 3줄을 바꿔야 하는 변수에 3줄의 숫자가 저장되어 있습니다 . 제 생각에는. 하지만 오류가 발생합니다.grep$oldsed "s/$old/$new/g" input > output

sed: 1: "s/\( 28.47969107 0. ...": unterminated substitute pattern

내 입력 파일은 다음과 같습니다.

scale
 1.000
primitive lattice vectors
    28.47969107  0.00000000  0.00000000
   0.00000000 28.47969107  0.00000000
   0.00000000  0.00000000 28.47969107
grid dimensions
  100 100 100

$old것은 선이다

28.47969107 0.00000000 0.00000000 0.00000000 28.47969107 0.00000000 0.00000000 0.00000000 28.47969107

$new형식은 이전과 동일하고 숫자만 다릅니다.

답변1

sed -e "/$old/i$new" -e "/$old/{N;N;d}" input > output

어디

  • $old28.47969107첫 번째 줄일 수도 있고 첫 번째 줄일 수도 있습니다.28.47969107 0.00000000 0.00000000
  • $new형태가 되어야 한다28.47969107 0.00000000 0.00000000\n0.00000000 28.47969107 0.00000000\n0.00000000 0.00000000 28.47969107

-z변수에서 이스케이프하는 다른 방법(최신 GNU sed(버전 >4.2.1) 및 옵션이 있는 경우) :newline

sed -z "s/$(printf "%b" "$old"|sed '$!s/$/\\/')/$(printf "%b" "$new"|sed 's/$/\\/')/" input > output

아니면 스크립트 할당 기능에서 대체를 하면

end_esc(){ printf "%b" "$@"|sed '$!s/$/\\/' ; }
sed -z "s/$(end_esc $old)/$(end_esc $new)/" input > output

답변2

먼저 예제 문자열을 정의해 보겠습니다 new.

$ new=$'1 2 3\n4 5 6\n7 8 9'

이제 다음 세 줄을 삭제 primitive lattice vectors하고 다음으로 바꾸겠습니다 new.

$ awk -v "new=$new" 'f==1{print new} f{f--;next} {print} /primitive/{f=3}' input
scale
 1.000
primitive lattice vectors
1 2 3
4 5 6
7 8 9
grid dimensions
  100 100 100

답변3

sed -e '$!N;$b' -e "/\n.*\n/!N;s/$old/$new/;t" -e P\;D

위 코드는 작동하지만 문제가 있습니다. 의 개행 문자 $old는 로 표현되어야 하고 \n, 의 개행 문자 $new앞에는 백슬래시가 와야 합니다 \. 값의 줄 바꿈으로 인해 문제가 발생합니다. 예를 들어, 확장 후:

sed 's/24.0000000001
.000000000000
.0000000000/...'

...작동하지 않습니다. 그건종료되지 않은 정규 표현식- 바라보다?

대신에:

old='num\nnum\nnum'
new='num\
num\
num'

...그게 전부입니다.

어떤 이유로 변수를 이스케이프하는 데 문제가 있는 경우 다음을 수행할 수 있습니다.

(  set -f; IFS='
'; printf '%s\\n' / .* '/!N;s/'$old
   printf '%s\\\n' */$new"/;t$IFS#"
)| sed -e '$N;$b' -f - -e P\;D input > output

그러나 이는 두 변수 모두에 빈 줄이 없어야 하며 이는 쉽지 않을 수 있습니다.

답변4

sed s/"$old"/"$new"/g나를 위해 일해

관련 정보