Cómo reemplazar todas las ocurrencias del patrón de cadena con un número que coincida con la cadena que depende del orden en que se encontraron las cadenas

Nov 25 2020

Necesito un script bash que busque cualquier cadena dentro <>, si encuentra una que no ha encontrado antes, debería reemplazarla con el valor actual del contador de índice (0 al principio) e incrementar el contador. Si encuentra dentro una cadena <>que ya conoce, debería buscar el índice de la cadena y reemplazarla con el índice. Esto debe hacerse en varios archivos, lo que significa que el contador no se reinicia cuando se buscan patrones en varios archivos, solo al iniciar el programa.

file_a.txt:

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

file_b.txt:

<c>
<b>

Debe convertirse

file_a.txt:

0
1
2
2
0

file_b.txt:

2
1

Lo que tengo hasta ahora:

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

Editar: Lo que no mencioné para simplificar el problema es que los patrones que deben reemplazarse no son el único texto dentro de los archivos, lo que significa que los archivos se ven así:
file_a.txt:

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

file_b.txt:

xyz<c>xyz
xyz<b>xyz

Debe convertirse

file_a.txt:

123abc0xyz
efg
1ah
a2
2b
c0

file_b.txt:

xyz2xyz
xyz1xyz

Debido a que los archivos pueden ser bastante grandes, no se deben copiar, solo editar. Esto debe hacerse para todos los archivos dentro de una carpeta y archivos en subcarpetas.

Respuestas

3 anubhava Nov 25 2020 at 03:10

Puede probar 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

Los archivos modificados se guardarán en el tmp/directorio y podrá volver a moverlos después de examinar su contenido.

cat tmp/file_a.txt

123abc0xyz
efg
1ah
a2
2b
c0

cat tmp/file_b.txt

xyz2xyz
xyz1xyz