使用AWK gsub()将字符序列替换为多个字符

使用AWK gsub()将字符序列替换为多个字符,awk,Awk,我试图通过用几个字符(两个*)替换几个相同的字母(超过3个)来转换文本 我的意见: ffffOOOOuuuurrrr fffffiiiiivvvvveeeee 我应该得到什么: **OOOO**** ******** 我的测试命令是: awk '{gsub(/[a-z]{4}/,"*"); print}' textfile 我不明白如何将{4}转换为“多于3” 还有如何打印两次(如相乘) 我还确信“超过三个”条件会将输入转换为: **OOOO** ** 有没有办法避免这种情况(替换一系列

我试图通过用几个字符(两个*)替换几个相同的字母(超过3个)来转换文本

我的意见:

ffffOOOOuuuurrrr
fffffiiiiivvvvveeeee
我应该得到什么:

**OOOO****
********
我的测试命令是:

awk '{gsub(/[a-z]{4}/,"*"); print}' textfile
我不明白如何将
{4}
转换为“多于3”

还有如何打印两次(如相乘)

我还确信“超过三个”条件会将输入转换为:

**OOOO**
**
有没有办法避免这种情况(替换一系列相同的字母)


或者不可能只使用一个小命令。

您提到的
sed
是标记中的一个选项:

echo "fffffiiiiivvvvveeeee" | sed 's/\([A-Za-z]\)\1\1\1\+/\1/g'
five
echo "fffffiiiiivvveeeee" | sed 's/\([A-Za-z]\)\1\1\1\+/\1/g'
fivvve

POSIX awk或sed不支持反向引用。您需要使用
gnu-sed
perl

sed -E 's/([a-z])\1{3,}/**/g' file
perl -pe 's/([a-z])\1{3,}/**/g' file

或者使用
perl

sed -E 's/([a-z])\1{3,}/**/g' file
perl -pe 's/([a-z])\1{3,}/**/g' file
正则表达式详细信息:

  • ([a-z])
    :匹配
    [a-z]
    并在组1中捕获
  • \1
    :第1组中捕获的字母的背面引用
  • {3,}
    :重复3次或更多次

以下是如何在假设区域设置中小写字母为a-z=ASCII 97-122的情况下处理任何awk:

$ cat tst.awk
{
    for (i=97; i<122; i++) {
        gsub(sprintf("%c{3,}",i),"**")
    }
    print
}

$ awk -f tst.awk file
**OOOO****
********
$cat tst.awk
{

用于(i=97;i使用
{4,}
匹配4个或更多。您只想匹配相同字符的重复?
[a-z]{4}
匹配任何4个小写字符,而不是相同的字符4次。要执行您想要的操作,您需要反向引用,这不是标准的
awk
。请参阅感谢您的解释,我尝试使用
sed
,但其语法对我来说似乎很复杂。选项
-E
表示反向引用?3个或更少将是de>{,3}
我猜,但是从2到4次怎么样。正如我提到的,它需要gnu使用。对于2到4次,使用
s/([a-z])\1{1,3}/**/g
,因为我们已经在组中匹配了一个字母。为了清楚起见,它不支持regexp**中的反向引用**。