计算化学公社

 找回密码 Forget password
 注册 Register
Views: 4181|回复 Reply: 9
打印 Print 上一主题 Last thread 下一主题 Next thread

[shell脚本] 请教bash shell在特定行&列的字符替换

[复制链接 Copy URL]

193

帖子

0

威望

4228

eV
积分
4421

Level 6 (一方通行)

跳转到指定楼层 Go to specific reply
楼主
各位老师好, 目前我想实现以下目的:将如下xyz文件从第四行开始(i.e.,坐标部分)的第一块(i.e atomic number)中的1,6改为H,C。应该怎么用bash实现?我尝试了sed -n '4,$p' file.xyz | awk -F " " '{gsub("1","H",$1)} 1' file.xyz, 但是修改后的内容和修改前的内容都存在,而不是我想实现的in-place替换, 谢谢!

0008noc H18C8 n-octane m062x_mg3s_geom
  
0 1
  6    0.0001270000    0.7622750000    0.0000000000
  6   -0.0001270000   -0.7622750000    0.0000000000
  6    1.4005600000    1.3639510000    0.0000000000
  6   -1.4005600000   -1.3639510000    0.0000000000
  1   -0.5483350000    1.1232240000    0.8756670000
  1   -0.5483350000    1.1232240000   -0.8756670000
  1    0.5483350000   -1.1232240000    0.8756670000
  1    0.5483350000   -1.1232240000   -0.8756670000
  6    1.4005600000    2.8886130000    0.0000000000
  6   -1.4005600000   -2.8886130000    0.0000000000
  1    1.9498930000    1.0037730000   -0.8756240000
  1    1.9498930000    1.0037730000    0.8756240000
  1   -1.9498930000   -1.0037730000   -0.8756240000
  1   -1.9498930000   -1.0037730000    0.8756240000
  6    2.8071160000    3.4761310000    0.0000000000
  6   -2.8071160000   -3.4761310000    0.0000000000
  1    0.8513920000    3.2460940000    0.8749630000
  1    0.8513920000    3.2460940000   -0.8749630000
  1   -0.8513920000   -3.2460940000    0.8749630000
  1   -0.8513920000   -3.2460940000   -0.8749630000
  1    2.7884900000    4.5653920000    0.0000000000
  1   -2.7884900000   -4.5653920000    0.0000000000
  1    3.3629520000    3.1507160000   -0.8804370000
  1    3.3629520000    3.1507160000    0.8804370000
  1   -3.3629520000   -3.1507160000   -0.8804370000
  1   -3.3629520000   -3.1507160000    0.8804370000


eureka

136

帖子

3

威望

4184

eV
积分
4380

Level 6 (一方通行)

10#
发表于 Post on 2019-3-12 02:07:31 | 只看该作者 Only view this author
这个目的和我之前想提取高斯log文件里坐标到PDB文件类似,贴个我自己用脚本,献丑了:

  1. #!/bin/bash
  2. input=$1

  3. #abc=$(sed -n "/Stationary/, /Population/"p $input | grep -A 100 Coordinates | sed -n "/\-\-/, /\-\-\-/"p | sed /\-\-\-/d)
  4. line=$(grep -n Coordinates $input | tail -1 | cut -f1 -d":") # line number of last step's coordinates
  5. abc=$(sed -n "${line},/Link/"p $input | sed '/[a-z]/d; /[A-Z]/d; /\-\-\-/d; /\=\=\=/d')
  6. xyz=$(echo -e "$abc" | awk '{for (i=1; i<=NR; i++); \
  7. if ($2=="1") $2="H"; \
  8. if ($2=="6") $2="C"; \
  9. if ($2=="7") $2="N"; \
  10. if ($2=="8") $2="O"; \
  11. if ($2=="16") $2="S"; \
  12. if ($2=="26") $2="Fe"}; \
  13. {printf " %-2s           %12.6f%12.6f%12.6f\n", $2,$4,$5,$6}')  # add more elements if it exists

  14. echo -e "$xyz" > temp_file
  15. line=$(cat temp_file | wc -l)
  16. for i in $(seq 1 $line)
  17. do
  18.    atom_name=$(sed -n ${i}p temp_file | awk '{print $1}')
  19.    XYZ=$(sed -n ${i}p temp_file | awk '{print $2,$3,$4}')
  20.    if [ $atom_name = 'Fe' ]
  21.    then
  22.       FE='FE'
  23.       echo -e "HETATM ${i} $FE UNK 1 $XYZ 0 0 $atom_name" |\
  24.       awk '{printf "%-6s%5d %-5s%-4s%5d%12.3f%8.3f%8.3f%6.2f%6.2f%12s\n", $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12}'
  25.    else
  26.       echo -e "HETATM ${i} $atom_name UNK 1 $XYZ 0 0 $atom_name" |\
  27.       awk '{printf "%-6s%5d  %-4s%-4s%5d%12.3f%8.3f%8.3f%6.2f%6.2f%12s\n", $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12}'
  28.    fi
  29. done
复制代码

评分 Rate

参与人数
Participants 1
eV +5 收起 理由
Reason
wuy069 + 5 赞!

查看全部评分 View all ratings

193

帖子

0

威望

4228

eV
积分
4421

Level 6 (一方通行)

9#
 楼主 Author| 发表于 Post on 2019-3-11 12:59:54 | 只看该作者 Only view this author
谢谢各位,受益匪浅
eureka

213

帖子

1

威望

2230

eV
积分
2463

Level 5 (御坂)

8#
发表于 Post on 2019-3-11 09:37:11 | 只看该作者 Only view this author
本帖最后由 abdoman 于 2019-3-11 10:04 编辑

xyz格式第一行应该是数字(表示原子数目),如果里面有数字1,会不会被错误的替换? 或者刚刚好100多个原子。

awk '{if(NF==4) {if($1==1) {print  "H ", $2, $3, $4} else {if($1==6) {print "C ",$2,$3,$4}}} else {print $0}} '  file.xyz

或者用printf 带格式 ,比较好看 。

评分 Rate

参与人数
Participants 1
eV +5 收起 理由
Reason
zsu007 + 5 赞!

查看全部评分 View all ratings

1043

帖子

0

威望

4106

eV
积分
5149

Level 6 (一方通行)

7#
发表于 Post on 2019-3-10 22:00:07 | 只看该作者 Only view this author
本帖最后由 granvia 于 2019-3-10 22:03 编辑
  1. sed 's/^ *1 / H /; s/^ *6 / C /' file.xyz
复制代码

1和6前面有无空格都适用

评分 Rate

参与人数
Participants 2
eV +4 收起 理由
Reason
Frank + 2 谢谢
Mikasa + 2

查看全部评分 View all ratings

1043

帖子

0

威望

4106

eV
积分
5149

Level 6 (一方通行)

6#
发表于 Post on 2019-3-10 21:50:32 来自手机 | 只看该作者 Only view this author
zsu007 发表于 2019-3-10 21:40
两句可以合并为一句 sed -i -e 's/ 1 / H /g; s/ 6 / C /g' *.xyz

最好把g去掉

评分 Rate

参与人数
Participants 2
eV +4 收起 理由
Reason
Frank + 2 谢谢
Mikasa + 2

查看全部评分 View all ratings

343

帖子

1

威望

6996

eV
积分
7359

Level 6 (一方通行)

5#
发表于 Post on 2019-3-10 21:40:28 | 只看该作者 Only view this author
Mikasa 发表于 2019-3-10 21:37
sed -i 's/ 1 / H /' *.xyz
sed -i 's/ 6 / C /' *.xyz
亲测可用,这个sed -i '/old/new/是用new替换文中 ...

两句可以合并为一句 sed -i -e 's/ 1 / H /g; s/ 6 / C /g' *.xyz

评分 Rate

参与人数
Participants 2
eV +4 收起 理由
Reason
Frank + 2 谢谢
Mikasa + 2 嗯嗯

查看全部评分 View all ratings

220

帖子

0

威望

5707

eV
积分
5927

Level 6 (一方通行)

跳跳猪

4#
发表于 Post on 2019-3-10 21:37:30 | 只看该作者 Only view this author
本帖最后由 Mikasa 于 2019-3-10 21:39 编辑

sed -i 's/ 1  / H  /' *.xyz
sed -i 's/ 6  / C  /' *.xyz
亲测可用,这个sed -i '/old/new/是用new替换文中的指定的old字符。
看你的文件里原子序号1和6前有一个空格、后有若干空格,而其它地没有这种数字加前后若干空格的情况,所以可以把‘ 1  ’和‘ 6  ’分别替换为‘ H  '和‘ C  ’。

评分 Rate

参与人数
Participants 1
eV +5 收起 理由
Reason
Frank + 5 谢谢 这个方法应该是最简单的

查看全部评分 View all ratings

流年似水,浮生如梦。

343

帖子

1

威望

6996

eV
积分
7359

Level 6 (一方通行)

3#
发表于 Post on 2019-3-10 21:36:41 | 只看该作者 Only view this author
本帖最后由 zsu007 于 2019-3-10 21:39 编辑

楼主用cat和awk搞定,awk里的参数根据你实际输出情况自行调整。该语句还可以将xyz里的元素自行设定为相应的元素符号。
cat *.xyz| awk ' {gsub(17, "Cl", $2) ; gsub(16,"S",$2); gsub("1", "H", $2); gsub(6, "C", $2); gsub(7, "N", $2); gsub(8, "O", $2); printf "%5s %10.6f %10.6f 10.6f\n",$2,$4,$5,$6}'

评分 Rate

参与人数
Participants 1
eV +2 收起 理由
Reason
Frank + 2 谢谢

查看全部评分 View all ratings

80

帖子

0

威望

3890

eV
积分
3970

Level 5 (御坂)

2#
发表于 Post on 2019-3-10 14:20:57 | 只看该作者 Only view this author
sed -r 's/^  1/  H/g' file.xyz | sed -r 's/^  6/  C/g'

评分 Rate

参与人数
Participants 1
eV +2 收起 理由
Reason
Frank + 2 谢谢

查看全部评分 View all ratings

手机版 Mobile version|北京科音自然科学研究中心 Beijing Kein Research Center for Natural Sciences|京公网安备 11010502035419号|计算化学公社 — 北京科音旗下高水平计算化学交流论坛 ( 京ICP备14038949号-1 )|网站地图

GMT+8, 2024-11-23 18:52 , Processed in 0.411878 second(s), 23 queries , Gzip On.

快速回复 返回顶部 返回列表 Return to list