使用sed替换所有以'xy'开头且长度为5以上的字符串

时间:2018-06-26 08:47:32

标签: unix sed aix

我正在运行AIX 6.1

我有一个文件,其中包含以某些特定字符开头的字符串/单词,例如“ xy”或“ Xy”或“ Xy”或“ XY”(不区分大小写),我需要用星号屏蔽整个单词/字符串如果单词大于5个字符,则为“ *”。

例如我需要一个sed命令,当对包含以下行的文件运行时...

This is a test line  xy12345  xy12  Xy123 Xy11111 which I need to replace specific strings

应该在下面给出输出

This is a test line xy12 which I need to replace specific strings

我尝试了以下命令(还没有达到我限制字长的阶段),但是它不起作用,并且显示全行,没有任何替换。

我尝试使用\ <和>以及\ b进行单词识别。

sed 's/\<xy\(.*\)\>/******/g' result2.csv
sed 's/\bxy\(.*\)\b******/g' result2.csv

5 个答案:

答案 0 :(得分:1)

您可以尝试使用awk:

echo 'This is a test line  xy12345  xy12  Xy123 Xy11111 which I need to replace specific strings' | awk 'BEGIN{RS=ORS=" "} !(/^[xX][yY]/ && length($0)>=5)'

awk记录分隔符设置为一个空格,以便能够获取每个单词的长度。

这适用于--posix--traditional模式下的GNU awk。

答案 1 :(得分:1)

使用sed进行心理锻炼

sed -E '
  s/(^|[[:blank:]])([xyXY])([xyXY].{2}[^[:space:]]*)([^[:space:]])/\1@\3@/g
  :A
  s/(@[^@[:blank:]]*)[^@[:blank:]](@[@]*)/\1@\2/g
  tA
  s/@/*/g'

此文本中不必包含@。

答案 2 :(得分:0)

您可以使用awk

s='This is a test line  xy12345  xy12  Xy123 Xy11111 which I need to replace specific strings xy123 xy1234 xy12345 xy123456 xy1234567'
echo "$s" | awk 'BEGIN {
    ORS=RS=" "
} 
{ 
    for(i=1;i<=NF;i++) {
        if(length($i) >= 5 && $i~/^[Xx][Yy][a-zA-Z0-9]+$/) 
            gsub(/./,"*", $i);
            print $i;
    } 
}'

一个衬板:

awk 'BEGIN {ORS=RS=" "} { for(i=1;i<=NF;i++) {if(length($i) >= 5 && $i~/^[Xx][Yy][a-zA-Z0-9]+$/) gsub(/./,"*", $i); print $i; } }'
# => This is a test line ******* xy12 ***** ******* which I need to replace specific strings ***** ****** ******* ******** *********

请参见online demo

详细信息

  • BEGIN {ORS=RS=" "}-awk的开头:将输出记录分隔符设置为等于空间记录分隔符
  • { for(i=1;i<=NF;i++) {if(length($i) >= 5 && $i~/^xy[a-zA-Z0-9]+$/) gsub(/./,"*", $i); print $i; } }-遍历每个字段(用for(i=1;i<=NF;i++)),如果当前字段($i)的长度等于或大于5(length($i) >= 5)并且匹配Xy和(&&)1个或更多字母数字字符模式($i~/^[Xx][Yy][a-zA-Z0-9]+$/),然后将每个字符替换为*(替换为gsub(/./,"*", $i)),然后打印当前字段值。

答案 3 :(得分:0)

一个简单的POSIX awk版本:

awk '{for(i=1;i<=NF;++i) if ($i ~ /^[xX][yY]/ && length($i)>=5) gsub(/./,"*",$i)}1'

但是,这并不能保持完整的间距(将多个空格转换为一个空格),以下内容可以做到:

awk 'BEGIN{RS=ORS=" "}(/^[xX][yY]/ && length($i)>=5){gsub(/./,"*")}1'

答案 4 :(得分:0)

这可能对您有用(GNU sed):

logItem

如果当前行不包含以sed -r ':a;/\bxy\S{5,}\b/I!b;s//\n&\n/;h;s/[^\n]/*/g;H;g;s/\n.*\n(.*)\n.*\n(.*)\n.*/\2\1/;ta' file 不区分大小写和5个或更多后继字符开头的字符串,则无需完成任何工作。

否则:

  1. 用换行符将字符串括起来
  2. 将图案空间(PS)复制到保留空间(HS)
  3. 用换行符xy代替所有字符
  4. 将PS附加到HS
  5. 用HS替换PS
  6. 在换行符之间交换字符串,保留第一行的其余部分
  7. 重复