如何用字符串替换一行中特定位置的范围?

huangapple go评论58阅读模式
英文:

How do I replace a specific range of positions in a line with a string?

问题

我有一个文件($pdbin),其中的行遵循特定的格式。我试图使用sed将字符57-60替换为字符串变量$o,仅在匹配两个特定模式的行上(包含HETATM和NO)。

这是一个我想要修改的示例行,其中突出显示了我想要更改的字符:

HETATM 1111  N   NO  A 204       4.938  19.295  -6.772  1.00 37.21           N
                                    ^^^^

这是我目前的sed命令,它替换了正确的字符(并保存到新文件$xyzin),但是通过搜索1.00而不是使用行上的位置:

sed "/HETATM/{/NO/{s/1.00/$o/g}}" $pdbin > $xyzin

我想要替换的变量$o是0.12

要将此命令修改为在位置57-60上操作,以便在我想要替换的字符串不匹配1.00时也能正常工作,您可以使用正则表达式中的位置匹配。下面是修改后的sed命令:

sed "/HETATM.*NO/ s/^\(.\{56\}\).\{4\}/$o/" $pdbin > $xyzin

这个命令会在包含"HETATM"和"NO"的行上,将第57到60个字符替换为变量$o的值。

英文:

I have a file ($pdbin) with lines following a specific format. I am trying to replace characters 57-60 with a string variable $o using sed, only on lines that match two specific patterns (contain HETATM and NO).

Here is an example line I want to modify, with the characters I want to change highlighted:

HETATM 1111  N   NO  A 204       4.938  19.295  -6.772  1.00 37.21           N
                                    ^^^^

Here is the sed command I have, which replaces the correct characters (and saves to new file $xyzin), but by searching for 1.00, not using the position on the line:

sed "/HETATM/{/NO/{s/1.00/$o/g}}" $pdbin > $xyzin

The variable $o I want to substitute in is 0.12.

How do I modify this command to operate on positions 57-60, so that it works if string I want to replace doesn't match 1.00?

答案1

得分: 2

你可以使用捕获组捕获前56个字符,并在替换中使用反向引用:

sed -E "/HETATM/{/NO/{s/(^.{56}).{4}/$o/;};}" "$pdbin" > "$xyzin"

cat "$xyzin"
HETATM 1111  N   NO  A 204       4.938  19.295  -6.772  0.12 37.21           N

(Note: I've provided the translated code part as requested.)

英文:

You can capture first 56 characters in a capture group and put it back in replacement using a back-reference:

sed -E "/HETATM/{/NO/{s/(^.{56}).{4}/$o/;};}" "$pdbin" > "$xyzin"

cat "$xyzin"
HETATM 1111  N   NO  A 204       4.938  19.295  -6.772  0.12 37.21           N

答案2

得分: 1

Using any awk in any shell on every Unix box:

$ awk -v o="$o" '/HETATM/ && /NO/{$0=substr($0,1,56) o substr($0,61)} 1' file
HETATM 1111  N   NO  A 204       4.938  19.295  -6.772  0.12 37.21           N

or more robustly by using full literal string comparisons on specific fields rather than partial regexp comparisons on the whole line:

$ awk -v o="$o" '($1=="HETATM") && ($4=="NO"){$0=substr($0,1,56) o substr($0,61)} 1' file
HETATM 1111  N   NO  A 204       4.938  19.295  -6.772  0.12 37.21           N
英文:

Using any awk in any shell on every Unix box:

$ awk -v o="$o" '/HETATM/ && /NO/{$0=substr($0,1,56) o substr($0,61)} 1' file
HETATM 1111  N   NO  A 204       4.938  19.295  -6.772  0.12 37.21           N

or more robustly by using full literal string comparisons on specific fields rather than partial regexp comparisons on the whole line:

$ awk -v o="$o" '($1=="HETATM") && ($4=="NO"){$0=substr($0,1,56) o substr($0,61)} 1' file
HETATM 1111  N   NO  A 204       4.938  19.295  -6.772  0.12 37.21           N

huangapple
  • 本文由 发表于 2023年6月8日 22:53:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76433132.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定