Mic*_*ant 9 array string uniq patterns
如果我有一个字符串“1 2 3 2 1” - 或一个数组 [1,2,3,2,1] - 我如何选择唯一值,即
"1 2 3 2 1" produces "1 2 3"
Run Code Online (Sandbox Code Playgroud)
或者
[1,2,3,2,1] produces [1,2,3]
Run Code Online (Sandbox Code Playgroud)
类似于 uniq 但 uniq 似乎适用于整行,而不是一行内的模式......
jim*_*mij 11
如果您使用的是 zsh:
$ array=(1 2 3 2 1)
$ echo ${(u)array[@]}
1 2 3
Run Code Online (Sandbox Code Playgroud)
或(如果KSH_ARRAYS
未设置选项)甚至
$ echo ${(u)array}
1 2 3
Run Code Online (Sandbox Code Playgroud)
使用 GNU awk
(这也保留原始顺序)
printf '%s\n' "1 2 3 2 1" | awk -v RS='[[:space:]]+' '!a[$0]++{printf "%s%s", $0, RT}'
1 2 3
Run Code Online (Sandbox Code Playgroud)
到read
成bash
阵列
read -ra arr<<<$(printf '%s\n' "1 2 3 2 1" |
awk -v RS='[[:space:]]+' '!a[$0]++{printf "%s%s", $0, RT}')
printf "%s\n" "${arr[@]}"
1
2
3
Run Code Online (Sandbox Code Playgroud)
对于具有任意值的数组,这是相当棘手的,bash
因为它没有内置的运算符。
bash
但是碰巧不支持在其变量中存储 NUL 字符,因此您可以利用它将其传递给其他命令:
相当于 的zsh
:
new_array=("${(@u}array}")
Run Code Online (Sandbox Code Playgroud)
在最近的 GNU 系统上,可能是:
eval "new_array=($(
printf "%s\0" "${array[@]}" |
LC_ALL=C sort -zu |
xargs -r0 bash -c 'printf "%q\n" "$@"' sh
))"
Run Code Online (Sandbox Code Playgroud)
或者,使用最新版本的bash
,并假设所有数组元素都不为空,您可以使用关联数组:
unset hash
typeset -A hash
for i in "${array[@]}"; do
hash[$i]=
done
new_array=("${!hash[@]}")
Run Code Online (Sandbox Code Playgroud)
使用 bash 4.4 及更新版本和 GNU sort
:
readarray -td '' new_array < <(
printf '%s\0' "${array[@]}" | LC_ALL=C sort -zu)
Run Code Online (Sandbox Code Playgroud)
在这些不同的解决方案中,元素的顺序不会相同。
和tcsh
:
set -f new_array = ($array:q)
Run Code Online (Sandbox Code Playgroud)
将保留第一个元素 ( a b a
=> a b
),例如zsh
的(u)
扩展标志。
set -l new_array = ($array:q)
Run Code Online (Sandbox Code Playgroud)
将保留最后一个 ( a b a
=> b a
)。然而,它们从数组中删除空元素。
归档时间: |
|
查看次数: |
13797 次 |
最近记录: |