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
Was dit nuttig?

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[@]}"
Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top