Linux

是否可以在 sed 中同時使用選項 -i 和 -E?

  • June 1, 2022

我有一個像

public class Constants {
   public static final String PACKAGE_VERSION = '1.24.0.1';
}

我正在執行腳本

sed -E "/PACKAGE_VERSION/s/\'([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\'/\'1.24.0.2\'/g" force-app/main/default/classes/Constants.cls > temp.cls
mv temp.cls force-app/main/default/classes/Constants.cls

用 ‘1.24.0.2’ 替換字元串 ‘1.24.0.1’

這可以用一條線做到這一點嗎?我應該使用awk而不是sed內聯編輯文件嗎?

當我嘗試執行命令時

sed -iE "/PACKAGE_VERSION/s/\'([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\'/\'1.24.0.3\'/g" force-app/main/default/classes/Constants.cls 

創建文件 Constants.clsE 而不是對目前文件進行內聯修改,並且新文件沒有替換。

當我嘗試執行命令時

sed -Ei "/PACKAGE_VERSION/s/\'([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\'/\'1.24.0.3\'/g" force-app/main/default/classes/Constants.cls 

我收到一個錯誤

sed: 1: "force-app/main/default/ ...": invalid command code f

我希望腳本在不更改腳本的情況下同時在 MacOS 和 Linux 中工作。

我嘗試使用awk,但我不明白如何使其內聯編輯文件?

當我嘗試執行以下

awk -v v="$version" '/PACKAGE_VERSION/{gsub(/[0-9]+(.[0-9]+){3}/,v)}1' force-app/main/default/classes/Constants.cls > force-app/main/default/classes/Constants.cls

這使我的文件空白

sed複製了就地編輯-i選項的不同實現,但不幸的是它們之間使用了不同的 API。perl

有些還為(高級)擴展正則表達式(POSIX 或其變體)添加了-Eor-r支持,有些-R甚至-P(非常)高級的類似 perl 的正則表達式(PCRE 或類似),但同樣(除了-E那將使到 POSIX 標準的下一個版本,並且現在在越來越多的實現中被發現),沒有普遍性。

在這裡,您不妨使用真實的東西並避免所有這些可移植性問題:

perl -i -pe "s{\bPACKAGE_VERSION\s*=\s*\K'\d+(\.\d+){3}'}{'1.24.0.3'}g" file

在某些 seds(至少是FreeBSD和 Mac 上的)中,該-i選項需要一個強制參數,該參數設置用於備份文件的後綴。你會寫-i.suffix, 或者-i .suffix在 shell 中,或者-i ""不給任何後綴。在那些中,要麼-iE-i -E將採用E-E作為參數-i而不是選項。

在其他一些 seds(至少GNU和 Busybox)中,該-i選項採用後綴的可選參數,這樣在同一命令行參數字元串中的任何內容都是後綴。它通常-i[suffix]以文件形式呈現。你會-i.suffix在 shell 中寫,或者只是-i不給任何後綴。在那些-iE仍然會做E後綴,但-i -E會作為兩個選項工作。

在這兩種情況下,都-iE意味著使用 suffix E,而在 FreeBSD/Mac 中,-Ei ...將以下參數作為後綴(您將 sed 程序放在問題中的那個)。

如果您想為沒有備份文件提供空後綴,這兩種方式是不兼容的。在這種情況下,您必須知道區別並-i "" -E與 FreeBSD/Mac 或-i -EGNU 一起使用。

或者,如果您想要備份文件或不在乎,只需使用-i.bak -E其中一個。(您以後可以隨時刪除備份文件。)

另請參閱如何使用 sed -i(就地編輯)實現可移植性?

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