(GNU)Sed:如何将第n个字符中的任何字符替换为第n + 10个字符?

时间:2014-03-06 13:51:12

标签: regex bash sed

我需要在字符串中替换第10到第20个字符,如下所示:

  

123456789012345678901234567890

到目前为止,我已经尝试过:

a)

仅适用于第10个角色: echo "123456789012345678901234567890" | sed 's/./X/10'

b)中 不适用于该范围:

echo "123456789012345678901234567890"  | sed 's/./X/10,20'
echo "123456789012345678901234567890"  | sed 's/./X/10\,20'
echo "123456789012345678901234567890"  | sed 's/./X/\{10,20\}'
echo "123456789012345678901234567890"  | sed 's/./X/\{10\,20\}'

不起作用,我收到错误

  

`s'

的未知选项

所以 - 问题是 - 如何使其发挥作用:

echo "123456789012345678901234567890" | sed 's/./X/10,20'

7 个答案:

答案 0 :(得分:5)

尝试:

$ sed -r "s/^(.{9})(.{11})/\1XXXXXXXXXX/" <<< 123456789012345678901234567890
123456789XXXXXXXXXX1234567890

答案 1 :(得分:1)

这是一个复杂的sed问题,我可以找到这个解决方案:

$ sed 's/^\(.\{10\}\)\(.\{10\}\)/\1XXXXXXXXXX/' <<< 123456789012345678901234567890
1234567890XXXXXXXXXX1234567890

使用awk它看起来更好:

$ awk 'BEGIN{FS=OFS=""} {for (i=10;i<=20;i++) $i="X"} {print}'  <<< 123456789012345678901234567890
123456789XXXXXXXXXXX1234567890

答案 2 :(得分:1)

您可以使用bash参数替换来执行此操作:

#!/bin/bash
s="123456789012345678901234567890"
l=${s:0:9}      # Extract left part
m=${s:10:11}    # Extract middle part
r=${s:20}       # Extract right part

# Diddle with middle part to your heart's content and re-assemble "$l$m$r" when done   
m=$(sed 's/./X/g' <<<$m)

有关更多说明和示例,请参阅here

或者,你可以这样做:

  1. 将字母行转换为一列,使每一行都在自己的行上
  2. 将您的编辑应用于LINES 10到20(而不是字符10到20)
  3. 将字母列转换回行(通过删除换行符)
  4. 如下面的单行中所示:

        $ echo "123456789012345678901234567890"  | sed "s/\(.\)/\1\n/g" | sed "10,20s/./X/" | tr -d "\n"
    

答案 3 :(得分:0)

我知道,它看起来很难看,但是:

 echo "123456789012345678901234567890" | \
  sed 's/^\(.\{10\}\).\{10\}\(.*\)/\1XXXXXXXXXX\2/'

答案 4 :(得分:0)

不在sed命令中放置多个X:

sed -r 's/^(.{9})(.{10,20})(.*)$/\1\n\2\n\3/' | sed -e '2s/./X/g' -e 'N;N;s/\n//g'

答案 5 :(得分:0)

要将 10th 替换为 20th 个字符,请尝试:

echo 123456789012345678901234567890 | sed 's/\(.\{9\}\).\{11\}/\1XXXXXXXXXX/'
123456789XXXXXXXXXX1234567890

使用GNU sed,您可以使用-r开关删除大部分反斜杠:

echo 123456789012345678901234567890 | sed -r 's/(.{9}).{11}/\1XXXXXXXXXX/'

或者天真的方法也适用于此:

echo 123456789012345678901234567890 | sed 's/\(.........\).........../\1XXXXXXXXXX/'

答案 6 :(得分:0)

这可能适合你(GNU sed):

sed ':a;/.\{9\}X\{11\}/!s/\(.\{9\}X*\)./\1X/;ta' file

或者带有一点句法糖:

sed -r ':a;/.{9}X{11}/!s/(.{9}X*)./\1X/;ta' file