Answers:
您可能需要查看uniq
和sort
应用程序。
./yourscript.ksh | 排序 优衣库
(仅供参考,是的,在此命令行中有必要进行排序,uniq
只删除彼此紧接的重复行)
编辑:
与亚伦·迪古拉(Aaron Digulla)关于uniq
的命令行选项发布的内容相反:
给出以下输入:
类 罐 罐 罐 箱子 箱子 爪哇
uniq
将只输出一次所有行:
类 罐 箱子 爪哇
uniq -d
将输出所有出现多次的行,并且将它们打印一次:
罐 箱子
uniq -u
将输出所有仅出现一次的行,并将其打印一次:
类 爪哇
sort
还提供了一个-u
用于提供唯一值的版本。
uniq
接缝只能处理相邻的线(至少默认情况下),这意味着sort
在送入之前可以输入uniq
。
对于可能不希望进行排序的较大数据集,您还可以使用以下perl脚本:
./yourscript.ksh | perl -ne 'if (!defined $x{$_}) { print $_; $x{$_} = 1; }'
基本上,这只是记住每条线的输出,因此不会再次输出。
与“ sort | uniq
”解决方案相比,它的优势在于无需预先排序。
使用zsh,您可以执行以下操作:
% 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:
% awk '!_[$0]++' infile
tar
more than one word
gz
java
class
awk
解决方案(有关说明,请参见stackoverflow.com/a/21200722/45375)将适用于大型文件。 )。该zsh
解决方案首先将整个文件读取到内存中,这对于大文件而言可能不是一个选择。同样,按照书面规定,只有没有嵌入空格的行才能正确处理;要解决此问题,请IFS=$'\n' read -d '' -r -A u <file; print -l ${(u)u}
改用。
(IFS=$'\n' u=($(<infile)); print -l "${(u)u[@]}")
[@]
后缀来引用数组的所有元素-似乎-至少从版本5开始-没有它就可以工作;还是只是为了清楚起见添加了它?
print -l "${(fu)$(<infile)}"
awk
示例输出。
将它们通过sort
和传送uniq
。这将删除所有重复项。
uniq -d
仅给出重复项,uniq -u
仅给出唯一的重复项(条带重复项)。
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[@]}"