bash를 사용하여 배열에서 중복 항목과 해당 인덱스를 찾고 싶습니다.
예를 들어 다음 배열이 있습니다.
arr=("a" "b" "c" "a" "c")
이 경우 인덱스 0과 3에서는 "a"가 반복되고, 인덱스 2와 4에서는 "c"도 반복됩니다.
현재 두 개의 중첩 루프를 사용하고 있지만 특히 큰 배열인 경우 속도가 너무 느립니다.
Bash에서 이 작업을 수행하는 더 좋고 효율적인 방법이 있습니까?
감사합니다!
답변1
awk를 사용하여 배열 요소를 입력으로 사용합니다.
$ printf '%s\n' "${arr[@]}" |
awk '{ elmnt[$0]= ($0 in elmnt? elmnt[$0] FS:"") NR-1 }
END{ for (e in elmnt) print e, elmnt[e] }'
a 0 3
b 1
c 2 4
새로운 요구사항의 경우(각 결과를 쉘 변수에 저장):
$ printf '%s\n' "${arr[@]}" |
awk -v q="'" '{ elmnt[$0]= ($0 in elmnt? elmnt[$0] FS:"") NR-1 }
END{ for (e in elmnt) print e, q elmnt[e] q }' OFS='='
a='0 3'
b='1'
c='2 4'
위의 명령 출력을 파일에 저장한 다음 export varfile
( varfile
파일 이름만)을 사용하여 파일을 내보내면 모든 변수가 쉘 변수로 내보내집니다.
답변2
매번 선형 스캔에 의존하지 않고도 연관 배열을 사용하여 값이 표시되었는지 확인할 수 있습니다.
#!/bin/bash
arr=("a" "b" "c" "a" "c")
declare -A values=()
for v in "${arr[@]}"; do
if [ "${values["x$v"]+set}" = set ]; then
echo "value '$v' is duplicate"
break
fi
values["x$v"]=1
done
unset values
단지 awk 처리된 값을 덤핑하는 것과 비교했을 때 얼마나 빠른지는 문제의 크기에 따라 달라질 수 있습니다. 쉘은 빠르지 않습니다. 특히 Bash는 매우 느립니다.