Shell

如何使用sed通過正則表達式替換一行並修改原始文件

  • September 14, 2022

我有一個像這樣的 nginx 配置文件:

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://demo.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://demo2.com/;
   }
}

我想如何使用 url1 替換第一個 proxy_pass 和 url2 替換 shell 中的第二個 proxy_pass,這是我的 shell 腳本,如下所示:

#!/usr/bin/env bash

set -u

set -e

set -x

echo "please input url1:"

read URL1

echo "$URL1"

echo "plase input url2:"

read URL2

echo "$URL2"


sed -E "12s/.*proxy\_pass.*/proxy\_pass:$URL1/" nginx.conf

sed -E "22s/.*proxy\_pass.*/proxy\_pass:$URL2/" nginx.conf

現在我遇到一個問題,sed沒有修改原始文件,只在終端輸出url,我應該怎麼做才能讓它修改原始配置文件?我想要這樣(輸入www.google.com;www.facebook.com;):

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 www.google.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 www.facebook.com;
   }
}

sed修改原始文件,您需要-i. 另外,請不要強迫您的使用者手動輸入內容。那隻會讓你的腳本更難使用:你不能輕易地重新執行,你不能自動化,而且很容易出錯。相反,讓腳本從命令行讀取 URL:

#!/usr/bin/env bash
set -u
set -e
set -x


sed -i -e "12s/.*proxy_pass.*/proxy_pass:$1;/" \
      -e "22s/.*proxy_pass.*/proxy_pass:$2;/" nginx.conf

不過,您可能應該進行備份,並且希望保持數據的對齊方式,而proxy_pass:文件中沒有,您有proxy_pass ,這看起來像正確的格式,因此請嘗試以下操作:

#!/usr/bin/env bash
set -u
set -e
set -x

timestamp=$(date +%s.%N)

sed -Ei."$timestamp".bak -e "12s/(.*proxy_pass ).*/\1$1;/" \
       -e "22s/(proxy_pass ).*/\1$2;/" nginx.conf

然後使用 IP 作為參數執行它:

$ foo.sh 1.2.3.4 5.6.7.8
++ date +%s.%N
+ timestamp=1663148866.892161961
+ sed -Ei.1663148866.892161961.bak -e '12s/(.*proxy_pass ).*/\11.2.3.4/' -e '22s/(proxy_pass ).*/\15.6.7.8;/' nginx.conf

這將創建一個名稱nginx.conf.1663148416.987587536.bak與原始nginx.conf文件類似的文件,並在nginx.conf.

引用自:https://unix.stackexchange.com/questions/717232