sed를 사용하여 텍스트를 바꿀 때 원본 파일 탭을 유지할 수 있습니까?

sed를 사용하여 텍스트를 바꿀 때 원본 파일 탭을 유지할 수 있습니까?

나는 쉘 스크립트의 일부 텍스트를 대체하기 위해 sed를 사용하고 있습니다. 이것은 다음과 같은 원본 파일입니다.

server {
    listen       80;
    server_name  localhost;

    location /api/test {
        proxy_connect_timeout 3000;
        proxy_send_timeout 3000;
        proxy_read_timeout 3000;
        send_timeout 3000;
        client_max_body_size 10M;
        client_body_buffer_size 100M;
        proxy_pass http://www.1.com;
    }

    location /api/demo {
        proxy_connect_timeout 3000;
        proxy_send_timeout 3000;
        proxy_read_timeout 3000;
        send_timeout 3000;
        client_max_body_size 10M;
        client_body_buffer_size 100M;
        proxy_pass http://www.2.com;
    }
}

이것은 내 쉘 스크립트입니다.

#!/usr/bin/env bash

set -u

set -e

# set -x

echo "please input url1:"

read URL1

echo "plase input url2:"

read URL2

URL1_ESCAPED_REPLACE=$(printf '%s\n' "$URL1" | sed -e 's/[\/&]/\\&/g')

URL2_ESCAPED_REPLACE=$(printf '%s\n' "$URL2" | sed -e 's/[\/&]/\\&/g')

timestamp=$(date +%s)

sed -Ei."$timestamp".bak -e "/\/api\/test/,/proxy\_pass/ s/.*proxy\_pass.*/proxy\_pass $URL1_ESCAPED_REPLACE;/" \
-e "/\/api\/demo/,/proxy\_pass/ s/.*proxy\_pass.*/proxy\_pass $URL2_ESCAPED_REPLACE;/" nginx.conf

이 스크립트는 잘 작동하지만 교체 작업으로 인해 공백 들여쓰기가 사라지는 문제에 직면했습니다. 공백을 제거하지 않고 텍스트만 바꿀 수 있습니까? 원본 텍스트 형식을 유지하고 싶습니다.

답변1

.*삭제 에 문제가 없다면 s/.*proxy\_pass문제가 해결될 것입니다. 문제는 다음과 일치하는 모든 문자열을 sed바꾸는 명령을 지정한다는 것입니다..*proxy_pass.*.*0회 이상의 모든 문자. 따라서 이 경우 이전과 이후의 모든 내용이 proxy_pass제거되므로 들여쓰기도 제거됩니다.

이 문제를 해결하려면 sed명령이 다음과 같아야 합니다.

sed -Ei."$timestamp".bak -e "/\/api\/test/,/proxy\_pass/ s/proxy\_pass.*/proxy\_pass $URL1_ESCAPED_REPLACE;/" \
-e "/\/api\/demo/,/proxy\_pass/ s/proxy\_pass.*/proxy\_pass $URL2_ESCAPED_REPLACE;/" nginx.conf

답변2

start를 사용하면 .*공백을 포함하여 일치하는 텍스트 앞의 모든 항목이 선택됩니다. 고정 텍스트로 바꾸면 proxy_pass모든 선행 공백이 제거됩니다. 공백을 유지하기 위해 바꾸기 명령을 변경할 수 있습니다( 사용 \1).

따라서 귀하의 코드는 다음과 같습니다.

timestamp=$EPOCHSECONDS

sed -Ei."$timestamp".bak -e "/\/api\/test/,/proxy_pass/ s/(.*proxy_pass).*/\1 $URL1_ESCAPED_REPLACE;/" \
-e   "/\/api\/demo/,/proxy_pass/ s/(.*proxy_pass).*/\1 $URL2_ESCAPED_REPLACE;/" infile

관련 정보