sedを使用して同時に削除して追加する

sedを使用して同時に削除して追加する

スクリプトに変更したい変数があります。

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/\1sedifLiverpool

答え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$citysed

関連情報