Use sed com variável em um loop for

1

Eu tenho o seguinte:

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

Mas a variável i não funciona

    
por ndfg201 02.05.2018 / 00:50

2 respostas

3

Incluindo o redirecionamento para o loop, você sobrescreve o test.txt em cada iteração. Em vez disso, você pode usar um loop para criar um script para sed e processar o arquivo com ele apenas uma vez:

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

Ou simplesmente:

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

Observe que ele ainda pode ser quebrado se a matriz contiver caracteres com significado especial no sed (que podem equivaler a uma vulnerabilidade de injeção de comando se o conteúdo da matriz não estiver totalmente sob seu controle).

    
por 02.05.2018 / 00:55
0

Suponho que você queira substituir todas as ocorrências de qualquer palavra em sua matriz arr pela palavra ANON .

Seu código funciona muito bem, mas você sobrescreve o arquivo de saída para cada iteração do loop, o que significa que o arquivo final terá apenas a última palavra da matriz substituída.

Também há um possível problema se alguma das palavras contiver caracteres que possam ser interpretados como caracteres de expressão regular, como * e [ , por exemplo.

Seria mais seguro fazer uma comparação exata de string para cada substituição. Você pode fazer isso com awk :

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

Isso substituirá todas as ocorrências do valor de str pela string ANON , mesmo que str contenha caracteres de expressão regular.

Para ler as strings de um arquivo (com o bônus adicional de que a segunda coluna do arquivo de string delimitado por tabulação contém a string a ser substituída):

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 }

Dado o arquivo de strings delimitado por tabulação strings as

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

... e o arquivo de texto file.txt as

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

... o código awk produziria

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

quando executado como

awk -f script.awk strings file.txt
    
por 07.05.2018 / 10:56