我正在尝试从目录中的多个文件替换重复的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技巧对我有用吗?
答案 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
因此,这一系列命令的作用是首先将重复项(如果有的话)排序到您选择的任何文件中。它获取这些重复项,并使用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 ''
。
答案 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