for (( i=30; i<=44; i++))
do
sed -i '28s/0.340d0/0."$i"0d0/' 1.txt
mv 1.txt "$i".txt
done
しかし、実行すると動作しません。 sed コマンド "$i" ループ内では動作しません。助けてください。 1.txtファイルの28行目の数字0.340doが、コピーされたファイルの0.30d0から0.440d0に置き換えられます。
答え1
コードには3つの問題があります。
一重引用符で囲まれた文字列を
sed
式として使用して、シェルがコマンドの代替セクションで変数を拡張するのを防ぎますs///
。元のファイル
1.txt
はその場所で変更されるため、シェルが変数を拡張してもループを介してパターンが2番目に一致しません(以前の反復でファイルが変更されたため)。1.txt
最初の反復でファイルを移動すると、各sed
後続の反復で「該当するファイルまたはディレクトリがありません」というエラーでコマンドが失敗します。
次の3つの問題を解決してください。
for number in {30..44}; do
sed '28 s/0\.340d0/0.'"$number"'0d0/' 1.txt >"$number.txt"
done
また、パターンの点が揃っていることを確認してください。言葉文字の代わりにドットを使用します(.
エスケープまたは未使用の場合に\.
実行されます[.]
)。式にはまだ一重引用符を使用していますが、一時的に破棄してシェル変数にsed
二重引用符の値を導入していますnumber
。
コマンドの結果は、変数をsed
使用してnumber
名前付きファイルに書き込まれます。
文字列で始まるという事実を使用することもできますrmin=
(これは次のように仮定されます)。ただこの文字列で始まる行):
for number in {30..44}; do
sed 's/^rmin=.*/rmin=0.'"$number"'0d0/' 1.txt >"$number.txt"
done
以下を使用すると、同じ操作をより簡潔に実行できますawk
。
for number in {30..44}; do
awk -v num="$number" 'FNR == 28 { printf "rmin=0.%.2d0d0\n", num; next }; 1' 1.txt >"$number.txt"
done
この方法の利点は、数値が10より小さい場合でも数値を正しく挿入することです(たとえば、forの代わりに0.020d0
create 0.20d0
)。2
または行rmin=
の先頭から一致させます。
for number in {30..44}; do
awk -v num="$number" '/^rmin=/ { printf "rmin=0.%.2d0d0\n", num; next }; 1' 1.txt >"$number.txt"
done
答え2
引用符のため、変数は30、31、32などではなく文字通り'
解釈されます。$i
sed式全体を引用符で囲むために、次のように変更しました"
。
for (( i=30; i<=44; i++))
do
sed "s/0.340d0/0.${i}0d0/g" 1.txt > temp.txt
cp temp.txt "$i".txt
done