Jak zamienić wszystkie wystąpienia wzorca łańcucha na liczbę pasującą do ciągu, która zależy od kolejności znalezienia ciągów
Potrzebuję skryptu bash, który wyszukuje dowolny ciąg w środku <>
, jeśli znajdzie taki, którego nie znalazł, zanim powinien zastąpić go bieżącą wartością licznika indeksu (0 na początku) i zwiększyć licznik. Jeśli znajdzie w środku łańcuch, <>
który już zna, powinien sprawdzić indeks tego ciągu i zastąpić go indeksem. Należy to zrobić dla wielu plików, co oznacza, że licznik nie resetuje się, gdy wiele plików jest przeszukiwanych w poszukiwaniu wzorców, tylko podczas uruchamiania programu
plik_a.txt:
<abc>
<b>
<c>
<c>
<abc>
file_b.txt:
<c>
<b>
Powinno stać się
plik_a.txt:
0
1
2
2
0
file_b.txt:
2
1
Co mam do tej pory:
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
Edycja: To, o czym nie wspomniałem, aby uprościć problem, to fakt, że wzorce, które powinny zostać zastąpione, nie są jedynym tekstem w plikach, co oznacza, że pliki wyglądają tak:
plik_a.txt:
123abc<abc>xyz
efg
<b>ah
a<c>
<c>b
c<abc>
file_b.txt:
xyz<c>xyz
xyz<b>xyz
Powinno stać się
plik_a.txt:
123abc0xyz
efg
1ah
a2
2b
c0
file_b.txt:
xyz2xyz
xyz1xyz
Ponieważ pliki mogą być dość duże, nie należy ich kopiować, a jedynie edytować. Należy to zrobić dla wszystkich plików w folderze i plików w podfolderach
Odpowiedzi
Możesz wypróbować ten skrypt 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
Zmodyfikowane pliki zostaną zapisane w tmp/
katalogu i możesz je przenieść z powrotem po sprawdzeniu ich zawartości.
cat tmp/file_a.txt
123abc0xyz
efg
1ah
a2
2b
c0
cat tmp/file_b.txt
xyz2xyz
xyz1xyz