我有一个ksh脚本,返回一长串以换行符分隔的数值,我想只看到唯一/不同的数值。这可能吗?
例如,假设我的输出是目录中文件后缀名的列表:
例如,假设我的输出是目录中文件后缀名的列表:
tar
gz
java
gz
java
tar
class
class
我想要看到像这样的列表: tar
gz
java
class
uniq
和sort
应用程序。
./yourscript.ksh | sort | uniq(FYI,是的,在此命令行中必须使用sort,
uniq
仅删除紧随其后的重复行)uniq
的命令行选项方面所发布的相反的是:class jar jar jar bin bin java
uniq
将仅输出所有行一次:
class jar bin java
uniq -d
将输出所有出现多次的行,并将它们打印一次:
jar bin
uniq -u
将输出所有仅出现一次的行,并将它们打印一次:
class java
sort -u
不需要在找到已经遇到的早期值时更新已排序列表。而 sort |
必须在将其传递给 uniq
之前对 所有 项目进行排序。 - whyersort -u
可能更快,因为任何最优比较排序算法的复杂度都是 O(n*log(n))
,但是使用哈希集数据结构可以在 O(n)
的复杂度下找到所有唯一值。尽管如此,sort -u
和 sort | uniq
的性能几乎相同,它们都很慢。我已经在我的系统上进行了一些测试,更多信息请参见 https://gist.github.com/sda97ghb/690c227eb9a6b7fb9047913bfe0e431d。 - Divano./script.sh | sort | uniq -u
没有输出任何内容。也许是因为输出太大了?虽然它并不是很大,但输出有 50,000 行,只有 4 个不同的值。 - Ferran Maylinch% 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
[@]
后缀来引用数组的所有元素 - 看起来至少在版本5中它可以不用;或者您只是为了清晰而添加了它? - mklement0print -l "${(fu)$(<infile)}"
- Dimitre Radoulovawk
示例输出。 - mklement0使用 AWK,您可以进行以下操作:
./yourscript.ksh | awk '!a[$0]++'
我发现它比sort和uniq更快
uniq -u
不是默认行为(有关详细信息,请参见我的答案中的编辑)。 - Matthew Scharley如果数据集较大,可能不希望排序,可以使用以下 Perl 脚本:
./yourscript.ksh | perl -ne 'if (!defined $x{$_}) { print $_; $x{$_} = 1; }'
这基本上只是记住每个输出行,以便不再输出它。
与"sort | uniq
"解决方案相比,它的优点在于不需要预先排序。
独特的,按要求(但未排序);
在测试时间内使用少于70个元素的系统资源更少;
编写以从stdin获取输入,
(或修改并包含在另一个脚本中):
(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[@]}"
我得到了一个更好的技巧,可以在文件中获取非重复条目
awk '$0 != x ":FOO" && NR>1 {print x} {x=$0} END {print}' file_name | uniq -f1 -u
sort
提供了一个-u
选项,可以使排序结果只保留唯一的值。 - Mingye Wanguniq
似乎默认只处理相邻的行,这意味着在输入之前可能需要对其进行排序。 - Stphanesort | uniq
花费了95秒。sort -u
花费了77秒。awk '!a[$0]++'
花费了9秒。所以awk胜出,但也是最难记住的。