Unix Shell 스크립트의 목록에서 고유 또는 별개의 값을 선택하십시오.
문제
나는 긴 값 목록을 반환하고 Newline 분리 된 KSH 스크립트가 있으며, 고유 한/별개의 값 만보고 싶습니다. 이것을 할 수 있습니까?
예를 들어 내 출력이 디렉토리의 파일 접미사라고 가정 해 봅시다.
tar gz java gz java tar class class
다음과 같은 목록을보고 싶습니다.
tar gz java class
해결책
당신은 그것을보고 싶을 수도 있습니다 uniq
그리고 sort
응용 프로그램.
./yourscript.ksh | sort | uniq
(FYI, 예,이 명령 줄에서 정렬이 필요합니다. uniq
서로 바로 뒤에있는 중복 선을 벗겨냅니다)
편집하다:
게시 된 것과는 반대로 Aaron Digulla 관련하여 uniq
의 명령 선 옵션 :
다음 입력이 주어지면 :
class jar jar jar bin bin java
uniq
모든 라인을 정확히 한 번 출력합니다.
class jar bin java
uniq -d
두 번 이상 나타나는 모든 라인을 출력하고 한 번 인쇄합니다.
jar bin
uniq -u
정확히 한 번 나타나는 모든 라인을 출력하면 한 번 인쇄합니다.
class java
다른 팁
정렬이 바람직하지 않은 더 큰 데이터 세트의 경우 다음 Perl 스크립트를 사용할 수도 있습니다.
./yourscript.ksh | perl -ne 'if (!defined $x{$_}) { print $_; $x{$_} = 1; }'
이것은 기본적으로 모든 라인 출력을 기억하여 다시 출력하지 않도록합니다.
그것은 ""에 비해 이점이 있습니다.sort | uniq
"정렬이 필요하지 않다는 솔루션.
와 함께 ZSH 당신은 이것을 할 수 있습니다 :
zsh-5.0.0[t]% cat infile
tar
more than one word
gz
java
gz
java
tar
class
class
zsh-5.0.0[t]% print -l "${(fu)$(<infile)}"
tar
more than one word
gz
java
class
또는 awk를 사용할 수 있습니다.
zsh-4.3.9[t]% awk '!_[$0]++' infile
tar
more than one word
gz
java
class
파이프를 통과하십시오 sort
그리고 uniq
. 이것은 모든 복제물을 제거합니다.
uniq -d
복제 만 제공하고 uniq -u
고유 한 것만 제공합니다 (스트립 복제).
당신이 할 수있는 awk를 사용하면 나는 정렬보다 더 빠릅니다.
./yourscript.ksh | awk '!a[$0]++'
요청에 따라 고유 한 (분류되지는 않았지만);
시간이 지남에 따라 ~ 70 개 미만의 요소에 대해 적은 수의 시스템 리소스를 사용합니다.
Stdin에서 입력하기 위해 작성,
(또는 다른 스크립트에 수정하고 포함) :
(세게 때리다)
bag2set () {
# Reduce a_bag to a_set.
local -i i j n=${#a_bag[@]}
for ((i=0; i < n; i++)); do
if [[ -n ${a_bag[i]} ]]; then
a_set[i]=${a_bag[i]}
a_bag[i]=$'\0'
for ((j=i+1; j < n; j++)); do
[[ ${a_set[i]} == ${a_bag[j]} ]] && a_bag[j]=$'\0'
done
fi
done
}
declare -a a_bag=() a_set=()
stdin="$(</dev/stdin)"
declare -i i=0
for e in $stdin; do
a_bag[i]=$e
i=$i+1
done
bag2set
echo "${a_set[@]}"