スクリプトに変更したい変数があります。
read -p "Enter the name of city: " city
if [[ $city =~ Liverpool ]]; then
sed -i -e "/\$type\_of\_city =/ s/= .*/= ${city}/" /cities
echo -e "Liverpool: `grep '$name_of_city' cities"
fi
#
都市ファイルには削除したい変数があります。
#$type_of_city = something
something
だから、上記のコードと実際に動作するように両方を変更したいのですが、Liverpool
フラグを削除する方法がわかりません#
。
今わかります#$type_of_city = Liverpool
。しかし、見たいです$type_of_city = Liverpool
。
答え1
コードブロックを少し修正し、
read -p "Enter the name of city: " city
if [ "$city" = 'Liverpool' ]
then
sed -Ei 's/^#* *(\$type_of_city) *= *.*/\1 = '"$city"'/' cities
printf "%s: %s\n" "$city" "$(grep -F "$city" cities)"
fi
ここでは、拡張 RE と行を一致させます^#* *(\$type_of_city) *= *.*
。細分化すると次のようになります。
^
- 行の始まり#*
- 0個以上の#
文字*
- 0個以上のスペース(
…)
- 囲むブロックと一致し、後で次のように使用されます。\1
\$type_of_city
- リテラル文字列$type_of_city
(\$
行末との間違った一致を防ぐためにエスケープ)*
- 0個以上のスペース=
- テキスト文字*
- 0個以上のスペース.*
- 0個以上の任意文字
一致が成功したら、行を次のように書き換えます。\1 = $city
ここでは、\1
括弧内の(
... )
ERE値、$city
は変数の値です。
変数の値を代替文字列$city
に直接入力するため、などの文字やシーケンスが含まれている場合は、せいぜい予期しない結果が生成されたり、エラーが発生する可能性があります。現在のコードでは、入力値が必要な句で保護されていますが、その句を削除するか、あまりにも軽減すると、この問題が発生する可能性があります。sed
/
\1
sed
if
Liverpool
答え2
あなたの場合は、行全体をに置き換えますsed
。ここでは、#
行の開始後のオプションの文字に固定されます。
sed "s/^#\{0,1\}\$type_of_city =.*/type_of_city = $city/" /cities
これは置き換えられます
#
行の始まり()の直後に0または1回表示され、^
その後に- リテラル文字列
$type_of_city =
の後に - 行末までのすべてのテキスト
があり、$type_of_city =
その後に内容が続きます。シェル変える$city
。
検索パターンが一致した場合にのみ置換が行われるため、使用するアドレス指定子は不要です。
ノートユーザー入力を取得するため、$city
入力を使用する前に検証/検証する必要があります。それ以外の場合はスクリプトが開きます。コード挿入の脆弱性ユーザーがsed
入力にコマンド構文を含む場合。
Stéphane Chazelasがコメントで指摘したように、コードに値を挿入する代わりに、環境を介してまたはパラメータにperl
値が渡される場所を使用してこれを回避できます。sed
$city
sed