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

関連情報