Linux 替换匹配行中的某些位置

Linux 替换匹配行中的某些位置,linux,bash,unix,sed,awk,perl,Linux,Bash,Unix,Sed,Awk,Perl,如果一行的开头是一个给定的字符串,我试图替换它的某些位置。以下是输入文件的示例: ... 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

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

...
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
有什么办法吗?

使用
sed

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

我想我应该使用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
格式字符串中具有适当的字段宽度。

具有:

使用
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

有趣的是,答案使用的是
sed
awk
perl
,但没有使用
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
读取行时
做
如果[[$line==TOTAL*];然后
extract=${line:19:8}
回显“${line/$extract/}”
其他的
回音“$line”
fi

完成与“如果找到总数,则第四和第五个字段为空”相同吗?@Kent是的,因为在创建纯文本文件之前,我正在从mysql查询导出CSV文件。谢谢!在查找“TOTAL”或“SUMA_u”时,有什么简单的方法可以避免使用两行代码吗?@jm_u非常欢迎!我已经添加了一行,其中包含您想要的解决方案。
awk '/^TOTAL/{$0= substr($0, 1, 19)"        "substr($0,28, length($0))}1' file
awk '/^TOTAL/{$0=sprintf("%s%27s", $1, $6)}1' file
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