Bash

如何替換匹配中的文本(但不是每個匹配)?

  • February 13, 2021

我想AllowOverride None從有/var/www/路徑的組中替換。我正在使用 sed 來執行此操作,但它正在替換每場比賽。

執行腳本之前的apache2.conf

<Directory />
   Options FollowSymLinks
   AllowOverride None
   Require all denied
</Directory>

<Directory /usr/share>
   AllowOverride None
   Require all granted
</Directory>

<Directory /var/www/>
   Options Indexes FollowSymLinks
   AllowOverride None
   Require all granted
</Directory>

執行腳本後的apache2.conf

<Directory />
   Options FollowSymLinks
   AllowOverride All
   Require all denied
</Directory>

<Directory /usr/share>
   AllowOverride All
   Require all granted
</Directory>

<Directory /var/www/>
   Options Indexes FollowSymLinks
   AllowOverride All
   Require all granted
</Directory>

script.sh

#!/bin/bash

sed "s/AllowOverride None/AllowOverride All/g" apache2.conf

**我的問題是:**我如何告訴 sed 替換它的位置/var/www/

您可以使用以下 Perl oneliner 實現此目的:

perl -0777 -pe 's{(<Directory\s/var/www/.*?AllowOverride\s)None(.*?</Directory>)}{$1All$2}gs' /tmp/file

這裡-0777的 flag 將行分隔符更改為 undef,因此 perl 會將文件讀取為一行(這可能是大文件的問題)。

-p循環文件行並列印它們, -e執行腳本, /tmp/file你的配置文件

s{(<Directory\s/var/www/.*?AllowOverride\s)None(.*?</Directory>)}{$1All$2}gs是與 /var/www 匹配目錄節的 2 部分並基本上將 None 替換為 All 的正則表達式。請注意,在 Perl 中,您可以使用 alsmot 任何符號作為正則表達式分隔符,在這種情況下,我使用{}//.

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