我有一个变量,它包含以下以空格分隔的条目。
variable="apple lemon papaya avocado lemon grapes papaya apple avocado mango banana"如何在不排序的情况下删除重复项?
#Something like this.
new_variable="apple lemon papaya avocado grapes mango banana"我在某个地方找到了一个脚本,它可以删除变量的重复项,但可以对内容进行排序。
#Not something like this.
new_variable=$(echo "$variable"|tr " " "\n"|sort|uniq|tr "\n" " ")
echo $new_variable
apple avocado banana grapes lemon mango papaya发布于 2009-12-09 18:02:04
new_variable=$( awk 'BEGIN{RS=ORS=" "}!a[$0]++' <<<$variable );下面是它的工作原理:
RS (输入记录分隔符)被设置为空白,以便它将$variable中的每个水果视为记录而不是字段。非排序的独特魔力发生在!a$0++中。由于awk支持关联数组,因此它使用当前记录($0)作为数组a[]的键。如果以前没有见过该键,则$0的计算结果为'0‘(awk未设置索引的默认值),然后取反以返回TRUE。然后,我利用了一个事实,即如果一个表达式返回TRUE,并且没有给出'{ commands }‘,那么awk将缺省为'print $0’。最后,$0被递增,使得这个键不再返回TRUE,因此不再打印重复的值。ORS (输出记录分隔符)也设置为一个空格,以模拟输入格式。
此命令的一个不太简洁的版本将产生相同的输出,如下所示:
awk 'BEGIN{RS=ORS=" "}{ if (a[$0] == 0){ a[$0] += 1; print $0}}'得到爱( awk =)
编辑
如果你需要用纯Bash 2.1+来做这件事,我建议你这样做:
#!/bin/bash
variable="apple lemon papaya avocado lemon grapes papaya apple avocado mango banana"
temp="$variable"
new_variable="${temp%% *}"
while [[ "$temp" != ${new_variable##* } ]]; do
temp=${temp//${temp%% *} /}
new_variable="$new_variable ${temp%% *}"
done
echo $new_variable;发布于 2009-12-09 20:34:51
此管道版本的工作原理是保留原始顺序:
variable=$(echo "$variable" | tr ' ' '\n' | nl | sort -u -k2 | sort -n | cut -f2-)发布于 2009-12-09 22:10:02
纯Bash:
variable="apple lemon papaya avocado lemon grapes papaya apple avocado mango banana"
declare new_value=''
for item in $variable; do
if [[ ! $new_value =~ $item ]] ; then # first time?
new_value="$new_value $item"
fi
done
new_value=${new_value:1} # remove leading blankhttps://stackoverflow.com/questions/1872692
复制相似问题