如何从给定字符串中查找不重复的字母

如何从给定字符串中查找不重复的字母

我有一个字符串aaabefhhhhhthkkd,我只需要从中提取非重复字母作为输出,保留顺序。

该字符串可以包含大写或小写字母。

输入:

aaabefhhhhhthkkd

输出:

beftd

需要如何定义这个逻辑才能获得上述所需的输出?

我尝试使用这个命令,但它只对我部分有用:

echo "aaabefhhhhhthkkd" | sed 's/./&\n/g' | uniq

上述部分运行命令的输出:

a
b
e
f
h
t
h
k
d

要测试的示例字符串:

String 1: aaabefhhhhhthkkd -> Output -> beftd

String 2: AAAbefhhhhhThkkD -> Output -> befTD 

String 3: AAAbefhMThkkD    -> Output -> befMTD 

答案1

uniq仅适用于相邻的重复项 - 因此如果您想使用它,您需要首先对输入进行排序,例如:

fold -w1 | sort | uniq -u | paste -sd ''
  • fold -w1与你的相同sed 's/./&\n/g',但不会引入额外的虚假换行符
  • sort使重复的字符相邻
  • uniq -u-u仅打印单例很重要
  • paste -sd ''将结果连接回一行

由于排序的原因,您将无法在所有情况下获得所需的输出顺序。

$ echo 'AAAbefhMThkkD' | fold -w1 | sort | uniq -u | paste -sd ''
  DMTbef

如果您不想推出自己的解决方案,您可以随时使用 Perl 的MoreUtils

$ echo 'AAAbefhMThkkD' |
    perl -MList::MoreUtils=singleton -ne 'print singleton split //'
befMTD

答案2

在每个 UNIX 机器上的任何 shell 中使用任何 awk:

$ echo 'aaabefhhhhhthkkd' |
    awk '{
        lgth = length()
        for (pos=1; pos<=lgth; pos++) {
            let = substr($0,pos,1)
            if ( gsub(let,"&") == 1 ) {
                printf "%s%s", let, (pos<lgth ? "" : ORS)
            }
        }
    }'
beftd

答案3

awk '
{
  n=split($0, a, "")
  for(i=1; i<=n; i++){
    if(gsub(a[i], "") == 1){ printf("%s", a[i]) }
  }
  print ""
}'
  • n=split($0, a, ""):a[1]成为字符串的第一个字符,a[2]第二个等n是字符总数。
  • for(i=1; i<=n; i++):让我们循环遍历所有数组a
  • if(gsub(a[i], "") == 1):删除a[i]字符串中的所有字符。如果字符串中只删除了一个字符,
    • printf("%s", a[i])打印该字符。
  • print ""处理完所有行后打印换行符。如果您只有一条输入线,则这是可选的。

压缩单行的示例:

$ awk '{n=split($0,a,"");for(i=1;i<=n;i++)if(gsub(a[i],"")==1)printf("%s",a[i])}' <<< AAAbefhMThkkD
befMTD

注意:POSIX 未定义按空字符串进行拆分。然而,gawk(GNU Awk),mawkoriginal-awk全部按要求执行操作。

答案4

主题的变化

echo 'aaabefhhhhhthkkd' | 
 awk '{while (length()>0) {t=substr($0,1,1); printf (gsub( t ,"")==1)?t:""} print}'

beftd

$0通过将第一个字符替换为直到空来进行消耗"",并在仅发生一次替换时打印。

相关内容