在多个文件中替换重复的uuid

时间:2018-11-02 00:22:36

标签: bash shell sed

我正在尝试从目录中的多个文件替换重复的UUID。甚至同一文件也可以具有重复的UUID。

我正在使用Unix实用程序来解决此问题。 到现在为止,我已经使用grep,cut,sort和uniq查找了文件夹中所有重复的UUID,并将其存储在文件中(例如repeat_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,但仍然在整个文件中重复了!

有什么sed技巧对我有用吗?

2 个答案:

答案 0 :(得分:0)

有很多方法可以做到这一点。如果您以后想要自定义内容,则使用函数的多命令方法可能会给您带来更大的灵活性,例如:

#!/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

因此,这一系列命令的作用是首先将重复项(如果有的话)排序到您选择的任何文件中。它获取这些重复项,并使用grepawk创建一个行号数组,每个重复项都可以找到。遍历数组(跳过第一个值)将允许将重复项替换为新的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 ''

答案 1 :(得分:0)

这对我有用:

#!/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