从匹配线替换某些位置

时间:2013-02-25 15:08:41

标签: linux bash unix sed awk

如果开头是给定字符串,我试图从一行替换某些位置。以下是输入文件的示例:

...
line1 with details 100 2566 1222
line2 with details 258 5874 5455
TOTAL text here    425 9589 8984

如果在大线上找到"TOTAL",我想用空格替换位置20到27:

...
line1 with details 100 2566 1222
line2 with details 258 5874 5455
TOTAL text here             8984

关于如何做的任何想法?

5 个答案:

答案 0 :(得分:4)

使用sed

sed 's/\(TOTAL.\{14\}\).\{8\}\(.*\)/\1        \2/' <file>

此解决方案捕获前19个字符,跳过以下8个字符,并捕获其余部分。

$ sed 's/\(TOTAL.\{14\}\).\{8\}\(.*\)/\1        \2/' <<EOF
...
line1 with details 100 2566 1222
line2 with details 258 5874 5455
TOTAL text here    425 9589 8984
EOF

...
line1 with details 100 2566 1222
line2 with details 258 5874 5455
TOTAL text here             8984

如果您有TOTALSUMA_,只需使用:

sed 's/\(\(TOTAL\|SUMA_\).\{14\}\).\{8\}\(.*\)/\1        \3/' <file>

答案 1 :(得分:2)

使用

perl -pe 's/TOTAL.{20}(.*)/sprintf "%s%s%s", "TOTAL", " "x20, $1/e' file.txt

答案 2 :(得分:1)

我想我会使用perl:

perl -pe 'substr($_,20,8," "x8 ) if /TOTAL/' input-file

但我认为你真正想要的是:

awk '/TOTAL/{ $2=""; $3="" } 1 ' input-file

但是,如果您需要保持格式相同,则可以执行以下操作:

awk '/TOTAL/{ printf( "%s%30s\n", $1, $4 ); next } 1' input-file

格式字符串中具有适当的字段宽度。

答案 3 :(得分:1)

使用awk

awk '/^TOTAL/{$0= substr($0, 1, 19)"        "substr($0,28, length($0))}1' file

或者,如果所有行都有相同数量的列

awk '/^TOTAL/{$0=sprintf("%s%27s", $1, $6)}1' file

答案 4 :(得分:1)

有趣的答案,使用sedawkperl,但没有使用bash。所以,这里是:

while read line
do
    if [[ $line == TOTAL* ]];then
        extract=${line:19:8}
        echo "${line/$extract/        }"
    else
        echo "$line"
    fi

done << END
line1 with details 100 2566 1222
line2 with details 258 5874 5455
TOTAL text here    425 9589 8984
END

这不完美,如果数字在同一行重复,那么我们就会遇到问题。