私は以下を持っています:
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
に置き換えられます。ANON
str
ファイルから文字列を読み取るには(追加の利点は、タブで区切られた文字列ファイルの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