Kies unieke of afsonderlike waardes van 'n lys in UNIX shell script
Vra
Ek het 'n KSH script wat 'n lang lys van waardes terug, newline geskei, en ek wil net die unieke / duidelike waardes te sien. Dit is moontlik om dit te doen?
Byvoorbeeld, sê my uitset is lêer agtervoegsels in 'n gids:
tar gz java gz java tar class class
Ek wil 'n lys soos sien:
tar gz java class
Oplossing
Jy mag dalk wil om te kyk na die uniq
en sort
aansoeke.
./yourscript.ksh | sort | uniq
(FYI, ja, die soort nodig in hierdie command line is, uniq
stroop net duplikaat lyne wat onmiddellik is ná mekaar)
Edit:
In teenstelling met wat is opgelaai deur Aaron Digulla met betrekking tot instruksies opsies uniq
se:
Gegewe die volgende insette:
class jar jar jar bin bin java
uniq
wil uitvoer al die lyne presies een keer:
class jar bin java
uniq -d
wil uitvoer al die lyne wat meer as een keer verskyn, en dit sal hulle een keer te druk:
jar bin
uniq -u
wil uitvoer al die lyne wat presies een keer verskyn, en dit sal hulle een keer te druk:
class java
Ander wenke
./script.sh | sort -u
Dit is dieselfde as monoksied se antwoord , maar 'n bietjie meer bondige.
Vir groter datastelle waar sortering kan nie wenslik wees, kan jy ook die volgende perl script gebruik:
./yourscript.ksh | perl -ne 'if (!defined $x{$_}) { print $_; $x{$_} = 1; }'
Dit basies net onthou elke lyn uitset sodat dit nie uitvoer dit weer.
Dit het die voordeel bo die "sort | uniq
" oplossing in dat daar geen sortering nodig voorlangs.
Met zsh jy kan dit doen:
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
Of jy kan AWK gebruik:
zsh-4.3.9[t]% awk '!_[$0]++' infile
tar
more than one word
gz
java
class
Pipe hulle deur sort
en uniq
. Dit verwyder al duplikate.
uniq -d
gee net die duplikate, uniq -u
gee net die unieke kinders (repies duplikate).
Met AWK wat jy kan doen, vind ek dit vinniger as soort
./yourscript.ksh | awk '!a[$0]++'
Unieke, soos versoek, (maar nie gesorteer);
gebruik minder hulpbronne stelsel vir minder as ~ 70 elemente (soos getoets met tyd);
geskryf om insette te neem van stdin, Woordeboek
(Of verander en sluit in 'n ander script):
(Bash)
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[@]}"