删除 bash 中的重复字符

Kis*_*han 5 command-line text-processing

如果我有一条线:

There are seven pencil
Run Code Online (Sandbox Code Playgroud)

我想将其打印为:

Ther a svn pcil
Run Code Online (Sandbox Code Playgroud)

什么是 bash shell 命令?

澄清:目标是删除所有,至少出现两次的字母,除了第一次出现。

Geo*_*iou 10

基于 sed 经典 synthax s/replace-this/with-that/gwhereg表示全局替换 = 所有出现次数,有人可以使用2g代替gwhich 表示global replacement but after second occurence(这是一个gnu sed扩展)。

仅删除的示例e

$ echo $a
there are seven pencil

$ echo $a | sed 's/e//2g'
ther ar svn pncil
Run Code Online (Sandbox Code Playgroud)

要删除所有重复的字母,我们可以使用以下技巧:

$ sed -f <(printf 's/%s//2g\n' {a..z}) <<<"$a"
ther a svn pcil
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不起作用: sed 's/[a-z]//2g'

上面的技巧使用<( )可以用作文件的进程替换。

在我的解决方案中,过程替换被视为sed脚本文件,sed通过-foption = read sed 命令从文件中提供。


Rom*_*est 5

Awk 解决方案(对于区分大小写的情况):

s="There are seven pencil"
printf '%s\n' "$s" | awk -v FS="" '{ 
           for(i=1; i<=NF; i++) 
               if ($i==" " || !a[$i]++) printf "%s", $i; print "" 
       }'
Run Code Online (Sandbox Code Playgroud)
  • -v FS="" - 设置“空”字段分隔符,以便每个字符成为一个单独的字段(不是 POSIX,而是很多实现支持的 GNU 扩展)
  • for(i=1; i<=NF; i++) - 迭代字符
  • if ($i==" " || !a[$i]++) - 如果它是空格字符或某个字符第一次出现

输出:

Ther a svn pcil
Run Code Online (Sandbox Code Playgroud)

对于不区分大小写的,替换a[$i]a[tolower($i)].