スラッシュを含めることができるファイルに最初に表示されるパターンを置き換えます。

スラッシュを含めることができるファイルに最初に表示されるパターンを置き換えます。

ありがとうこのリンク私はどうするか知っていますスラッシュを含む変数を渡すsedパターンで:

sed "s~$var~replace~g" $file。 / 代わりにシングルバイト文字を使用してください。

ありがとうこの他のリンク私も知る方法ファイルに最初に表示されるパターンのみを置き換える(同じ行にはありません):

sed "0,/$var/s/$var/replacement/" filename または sed 0,/$var/{s/$var/replacement/} filename

しかし、それを行うと( sed '0,~$var~s~$var~replacement~' filename またはゼロで始まり、スラッシュがない他のもの)エラーが発生します。unknown command: '0'

この2つをどのように組み合わせることができますか?おそらくawkやPerlを使うか…?

ベストアンサー1

しかし:

sed "0,\~$var~s~$var~replacement~"

正規表現の区切り文字を変更するために使用できます。sed通常、コード(または他のインタプリタ)コードに変数拡張を含めることは非常に賢明ではありません。

まず、この区切り文字はエスケープする必要がある唯一の文字ではありません。これはすべての正規表現演算子にも必要です。

しかし、より重要なことは、特にGNUの場合、sedこれはコマンドインジェクションの脆弱性です。コンテンツを$var制御できない場合は、任意のデータをeval

たとえば、次のようになります。

$ var='^~s/.*/uname/e;#'
$ echo | sed "0,\~$var~s~$var~replacement~"
Linux

コマンドunameが実行され、幸い今回は無害でした。

GNU以外sedの実装では任意のコマンドを実行することはできませんが、コマンドを使用してすべてのファイルを上書きすることができます。wこれは実際には同じです。

より正確な方法は$varまず、問題のある文字を脱出してください:

NL='
'
case $var in
  (*"$NL"*)
    echo >&2 "Sorry, can't handle variables with newline characters"
    exit 1
esac
escaped_var=$(printf '%s\n' "$var" | sed 's:[][\/.^$*]:\\&:g')
# and then:
sed "0,/$escaped_var/s/$escaped_var/replacement/" < file

別の方法は、次のものを使用することですperl

var=$var perl -pe 's/\Q$ENV{var}\E/replacement/g && $n++ unless $n' < file

$var渡されたコード内の内容を拡張せずにperl(別のコマンドインジェクションの脆弱性になる可能性があります)、代わりにperlその内容を正規表現処理の一部に拡張します(\Q...\Eつまり、正規表現演算子が特に処理されないことを意味します)。

改行文字が含まれている場合は、$var最後に 1 つだけで一致が可能です。あるいは、-0777入力が1行ずつ処理されず、単一のレコードとして処理されるようにこのオプションを渡すこともできます。

おすすめ記事