そうですね、必要なことを実行する方法が見つからないようです。
次のようなテキストファイル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 に変更しますが、次の反復でインデックス 30 の 2 つのブロック (変更されたブロックと元のブロック) が見つかることです。
すでに変更されたインデックスを上書きせずにこれを行うにはどうすればよいですか?
わかりました、ありがとうございます。改善のために質問を編集します。次のような 2 つのインデックスがある場合、同様の操作を実行するにはどうすればよいですか。
(freqBiasL2[32][100])
(SatBiasL1[32][101])
(defSatBiasL2_L1[32][102])
(defSatBiasSlope[32][103])
(defSatBiasSigma[32][104])
最初のインデックスを無視して、2 番目のインデックスのみを増分したいですか?
答え1
perl を使用します:
perl -pe 's/(?<=\[)(\d+)(?=\])/$1+1/ge' prova.txt
説明:
-p
すべての行をループし、各行の後に結果を出力することを意味します。-e
各行で実行する式を定義しますs/from/to/
単純な置換を行うs/(\d+)/$1+1/ge
は 1 つ以上の数字と一致し、それを にキャプチャし$1
、e
末尾の修飾子によって、置換文字列が式であることを perl に伝えます。 は、に 1$1+1
を加えた値を置換します。修飾子は、この置換をグローバルに、つまり 1 行に複数回実行することを意味します。$1
g
(?<=\[)
は、長さがゼロの肯定的な後読みアサーションです。つまり、その後に続くものは、その前に(正規表現の特殊トークンとして[
エスケープする必要がある) がある場合にのみ一致します。長さがゼロであるということは、置換対象の一部ではないことを意味します。\
[
(?=\])
は、長さがゼロの正の先読みアサーションです。つまり、その前にあるものは、]
(これもエスケープされています) が続く場合にのみ一致します。
したがって、これは から までのすべての数値を取得し[
、]
その数値を増分します。
答え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) .
(空白のある点) が必要なのかはわかりません。