forループでsedと変数を使用する

forループでsedと変数を使用する

私は以下を持っています:

for i in "${arr[@]}"
do
sed -r "s/$i/ANON/g" /log > /test.txt
done

しかし、変数iは機能しません。

答え1

ループにリダイレクトを含めると、繰り返しtest.txtごとに上書きされます。ループを使用してスクリプトを生成し、sedそれを使用してファイルを一度だけ処理できます。

for i in "${arr[@]}" ; do
    printf 's/%s/ANON/g\n' "$i"
done | sed -r -f- /log > /test.txt

または簡単に:

printf 's/%s/ANON/g\n' "${arr[@]}" | sed -r -f- /log > /test.txt

配列にsedに特別な意味を持つ文字が含まれていると、まだ破損する可能性があります(配列の内容を完全に制御できない場合は、コマンド注入の脆弱性に該当する可能性があります)。

答え2

arr配列内のすべての単語をwordに置き換えたいとしますANON

コードは正常に動作しますが、ループが繰り返されるたびに出力ファイルが上書きされます。つまり、最終ファイルは配列の最後の単語のみを置き換えます。

単語に正規表現文字(たとえば、および)として解釈できる文字が含まれている場合でも、*潜在的な問題があります。[

すべての置換に対して正確な文字列比較を実行する方が安全です。次の方法でこれを実行できますawk

{
    while (offset = index($0, str))
        $0 = substr($0, 1, offset - 1) "ANON" substr($0, offset + length(str))
}
{ print }

正規表現文字が含まれていても、その値のすべての項目が文字列strに置き換えられます。ANONstr

ファイルから文字列を読み取るには(追加の利点は、タブで区切られた文字列ファイルの2番目の列に置き換える文字列が含まれることです):

BEGIN { FS = "\t" }
NR == FNR { str[$1] = $2; next }
{
    for (s in str) {
        sl = length(s)
        while (offset = index($0, s))
            $0 = substr($0, 1, offset - 1) str[s] substr($0, offset + sl)
    }
}
{ print }

タブ区切り文字列ファイルをstrings次のように指定します。

*password*    *redacted*
My Name       Not really my name

...テキストファイルfile.txtは次のとおりです。

Password for the account belonging to My Name: *password*

... awkコードが生成されます

Password for the account belonging to Not really my name: *redacted*

次のように実行するとき

awk -f script.awk strings file.txt

関連情報