英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论