Como substituir todas as ocorrências do padrão de string por um número correspondente à string que depende da ordem em que as strings foram encontradas

Nov 25 2020

Preciso de um script bash que procure qualquer string dentro <>, se encontrar alguma que não tenha encontrado antes, deve substituí-la pelo valor atual do contador de índice (0 no início) e incrementar o contador. Se ele encontrar uma string dentro <>que já conhece, ele deve procurar o índice da string e substituí-lo pelo índice. Isso deve ser feito em vários arquivos, o que significa que o contador não zera quando vários arquivos são pesquisados ​​para os padrões, apenas na inicialização do programa

file_a.txt:

<abc>
<b>
<c>
<c>
<abc>

file_b.txt:

<c>
<b>

Deve se tornar

file_a.txt:

0
1
2
2
0

file_b.txt:

2
1

O que consegui até agora:

names=()
for file in folder/*.txt
do
    name=$(sed 's/\<[a-zA-Z]*\> /\1 /' file) for i in "${names[@]}"
    do
        if [ "$i" -eq "$name" ]
        then
            #replace string with index of string in array
        else
            names+=("$name")
        fi
    done
done

Edit: O que não mencionei para simplificar o problema é que os padrões que devem ser substituídos não são o único texto dentro dos arquivos, o que significa que os arquivos têm a seguinte aparência:
file_a.txt:

123abc<abc>xyz
efg
<b>ah
a<c>
<c>b
c<abc>

file_b.txt:

xyz<c>xyz
xyz<b>xyz

Deve se tornar

file_a.txt:

123abc0xyz
efg
1ah
a2
2b
c0

file_b.txt:

xyz2xyz
xyz1xyz

Como os arquivos podem ser muito grandes, eles não devem ser copiados, apenas editados. Isso deve ser feito para todos os arquivos dentro de uma pasta e arquivos em subpastas

Respostas

3 anubhava Nov 25 2020 at 03:10

Você pode tentar este script awk:

mkdir -p tmp

awk 'match($0, /<[^>]+>/) { k = substr($0, RSTART, RLENGTH)
   if (!(k in freq))
      freq[k] = n++
   $0 = substr($0, 1, RSTART-1) freq[k] substr($0, RSTART+RLENGTH) } { print $0 > ("tmp/" FILENAME)
}' file_{a,b}.txt

Os arquivos modificados serão salvos no tmp/diretório e você pode movê-los de volta após examinar seu conteúdo.

cat tmp/file_a.txt

123abc0xyz
efg
1ah
a2
2b
c0

cat tmp/file_b.txt

xyz2xyz
xyz1xyz