好吧,看來我找不到辦法做我需要的事情。
假設我有一個像這樣的文字檔 A
(freqBiasL2[27])
(SatBiasL1[27])
(defSatBiasL2_L1[27])
(defSatBiasSlope[27])
(defSatBiasSigma[27])
(freqBiasL2[28])
(SatBiasL1[28])
(defSatBiasL2_L1[28])
(defSatBiasSlope[28])
(defSatBiasSigma[28])
(freqBiasL2[29])
(SatBiasL1[29])
(defSatBiasL2_L1[29])
(defSatBiasSlope[29])
(defSatBiasSigma[29])
等等。我想更改 [] 括號之間的索引,使得每個索引 i = i+3。
我嘗試了 for 迴圈和 sed 的組合,但不起作用
for i in {27..107..1}
do
i_new=$((i+3))
sed -e 's/\['$i'\]/\['$i_new'\]/' prova.txt
done
問題是它會將前 27 個更改為 30 個,但在下一次迭代中它將找到 2 個索引為 30 的區塊(更改後的區塊和原始區塊)。
如何在不覆蓋已經更改的索引的情況下做到這一點?
好的,謝謝,我編輯我的問題以進行改進:如果我有 2 個索引,我該如何做類似的事情:
(freqBiasL2[32][100])
(SatBiasL1[32][101])
(defSatBiasL2_L1[32][102])
(defSatBiasSlope[32][103])
(defSatBiasSigma[32][104])
我只想增加第二個索引而忽略第一個索引?
答案1
使用perl:
perl -pe 's/(?<=\[)(\d+)(?=\])/$1+1/ge' prova.txt
解釋:
-p
意味著循環每一行並在每一行之後列印結果-e
定義在每一行執行的表達式s/from/to/
做一個簡單的替換s/(\d+)/$1+1/ge
匹配一個或多個數字,將其捕獲到 中$1
,然後e
末尾的修飾符告訴 perl 替換字串是一個表達式:替換加 1$1+1
的值。$1
g
(?<=\[)
是一個正的零長度lookbehind斷言。這意味著它後面的內容僅在其前面的情況下匹配[
(需要使用\
as[
是正則表達式中的特殊標記進行轉義)。零長度意味著它不屬於將被替換的部分。(?=\])
是正的零長度先行斷言。這意味著它前面的內容只有在它後面跟著]
(再次轉義)時才匹配。
因此,這將獲取 和 之間的所有數字[
並]
增加該數字。
答案2
您也可以使用awk
:
awk -F '[\\[\\]]' '{if ($2) { sub($2, $2 + 3)}} 1' prova.txt
事實上,這可以稍微縮短為:
awk -F '[\\[\\]]' '$2 { sub($2, $2 + 3)} 1' prova.txt
答案3
我知道您已經解決了您的問題,但僅供參考,您可以透過對程式碼進行非常簡單的修改來解決它:透過反轉您循環的序列。
使用{107..27..-1}
(或更簡潔地說{107..27}
)就足以解決您的問題,因為在替換 30 時,只會找到原始的 30,而 27 尚未被替換。
答案4
好吧,我想我已經找到了雙索引的解決方案以及修改 cas 的命令。這使得工作:
perl -p -e 's/\[(\d+)\]\[(\d+)\]/"[" . ($1) . "][" . ($2+40) . "]"/ge' prova.txt
順便不確定為什麼我需要. ($1) .
(用空格點)。