在UNIX shell脚本中从列表中select唯一或不同的值
我有一个ksh脚本,返回一个很长的值列表,换行符分隔,我想只看到唯一/不同值。 有可能做到这一点?
例如,假设我的输出是目录中的文件后缀:
tar gz java gz java tar class class
我想看到一个像这样的列表:
tar gz java class
您可能需要查看uniq
并对应用程序进行sort
。
./yourscript.ksh | sorting| uniq的
(仅供参考,是的,sorting在这个命令行中是必须的, uniq
只删除紧接在一起的重复行)
编辑:
与Aaron Digulla发布的uniq
命令行选项相反:
鉴于以下input:
类 jar jar jar 箱子 箱子 java的
uniq
会输出所有的行只有一次:
类 jar 箱子 java的
uniq -d
会输出所有显示不止一次的行,并且会打印一次:
jar 箱子
uniq -u
会输出所有只出现一次的行,并且会打印一次:
类 java的
./script.sh | sort -u
这与一氧化碳的 答案是一样的 ,但更简洁一点。
对于更大的数据集,可能不需要sorting,也可以使用以下perl脚本:
./yourscript.ksh | perl -ne 'if (!defined $x{$_}) { print $_; $x{$_} = 1; }'
这基本上只是记住每一行输出,所以它不会再输出。
与“ sort | uniq
”解决scheme相比,它的优势在于不需要预先分类。
通过sort
和uniq
pipe他们。 这将删除所有重复项。
uniq -d
只给出重复项, uniq -u
只给出唯一的重复项(strip duplicates)。
用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
独特的,按要求(但不sorting);
使用less于70个元素的系统资源(按时间testing);
写从inputstdin,
(或修改并包含在另一个脚本中):
(击)
bag2set () { # Reduce a_bag to a_set. local -iijn=${#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 -ii=0 for e in $stdin; do a_bag[i]=$e i=$i+1 done bag2set echo "${a_set[@]}"
用AWK你可以做,我发现它比sorting更快
./yourscript.ksh | awk '!a[$0]++'