Замена дубликата UUID в нескольких файлах - PullRequest
0 голосов
/ 02 ноября 2018

Я пытаюсь заменить дубликаты UUID из нескольких файлов в каталоге. Даже один и тот же файл может иметь дубликаты UUID.

Я использую утилиты Unix для решения этой проблемы. До сих пор я использовал grep, cut, sort и uniq, чтобы найти все дубликаты UUID в папке и сохранить их в файле (скажем, duplicate_uuids)

Затем я попытался sed заменить UUID, просматривая файл.

filename="$1"
re="*.java"
while read line; do
    uuid=$(uuidgen)
    sed -i'.original' -e "s/$line/$uuid/g" *.java
done < "$filename"

Как и следовало ожидать, в итоге я заменил все дубликаты UUID новыми UUID, но, тем не менее, они дублируются по всему файлу!

Есть ли какой-нибудь седь-трюк, который может работать на меня?

Ответы [ 2 ]

0 голосов
/ 02 ноября 2018

Это сработало для меня:

#!/bin/bash

duplicate_uuid=$1
# store file names in array
find . -name "*.java" > file_names
IFS=$'\n' read -d '' -r -a file_list < file_names

# store file duplicate uuids from file to array
IFS=$'\n' read -d '' -r -a dup_uuids < $duplicate_uuid

# loop through all files
for file in "${file_list[@]}"
do
    echo "$file"
    # Loop through all repeated uuids
    for old_uuid in "${dup_uuids[@]}"
    do
        START=1
        # Get the number of times uuid present in this file
        END=$(grep -c $old_uuid $file)
        if (( $END > 0 )) ; then
            echo "    Replacing $old_uuid"
        fi
        # Loop through them one by one and change the uuid
        for (( c=$START; c<=$END; c++ ))
        do
            uuid=$(uuidgen)
            echo "         [$c of $END] with $uuid"
            sed -i '.original' -e "1,/$old_uuid/s/$old_uuid/$uuid/" $file
        done
    done
    rm $file.original
done
rm file_names
0 голосов
/ 02 ноября 2018

Существует множество способов сделать это. Использование многокомпонентного подхода с использованием функции может дать вам большую гибкость, если вы захотите настроить вещи позже, например:

#!/bin/bash

checkdupes() {
    files="$*"
    for f in $files; do
        filename="$f"
        printf "Searching File: %s\n" "${filename}"
        while read -r line; do
            arr=( $(grep -n "${line}" "${filename}" | awk 'BEGIN { FS = ":" } ; {print $1" "}') )
            for i in "${arr[@]:1}"; do
                sed -i '' ''"${i}"'s/'"${line}"'/'"$(uuidgen)"'/g' "${filename}"
                printf "Replaced UUID [%s] at line %s, first found on line %s\n" "${line}" "${i}" "${arr[0]}"
            done
        done< <( sort "${filename}" | uniq -d )
    done
}

checkdupes /path/to/*.java

Итак, эта серия команд сначала сортирует дубликаты (если они есть) в любом выбранном вами файле. Он берет эти дубликаты и использует grep и awk для создания массива номеров строк, в котором найден каждый дубликат. Зацикливание массива (при пропуске первого значения) позволит заменить дубликаты новым UUID, а затем повторно сохранить файл.

Использование файла дубликата списка :

Если вы хотите использовать файл со списком дубликатов для поиска в других файлах и заменить UUID в каждом из них, которые соответствуют, это просто вопрос изменения двух строк:

Заменить:

for i in "${arr[@]:1}"; do

С:

for i in "${arr[@]}"; do

Заменить:

done< <( sort "${filename}" | uniq -d )

С:

done< <( cat /path/to/dupes_list )

ПРИМЕЧАНИЕ : если вы не хотите перезаписывать файл, удалите sed -i '' в начале команды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...