LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1249|回复: 12

【完成】求教:如何将一个文件的数据全部放到另一个文件指定位置

[复制链接]
发表于 2005-12-12 09:13:39 | 显示全部楼层 |阅读模式
大家好,现有两个文件
a1.file内容如下:

  1. @<TRIPOS>MOLECULE
  2. B29_t1
  3. 42 44 0 0 0
  4. SMALL
  5. GAST_HUCK

  6. @<TRIPOS>ATOM
  7.       1 N1         -2.5973    0.0125    0.0420 N.am    1  <1>         0.0000
  8.       2 O1         -3.5374    1.0156    1.9351 O.2     1  <1>         0.0000
  9.       3 O2         -2.2592   -1.4277   -1.7714 O.2     1  <1>         0.0000
  10.       4 C1          1.1189    2.0075    0.0131 C.ar    1  <1>         0.0000
  11.       5 C2          1.0694    0.6283    0.2742 C.ar    1  <1>         0.0000
  12.       6 C3         -0.1779    0.0020    0.2786 C.ar    1  <1>         0.0000
  13.       7 H1         -0.2337   -1.0620    0.4801 H       1  <1>         0.0000
  14.       8 C4         -1.3566    0.6994    0.0155 C.ar    1  <1>         0.0000
  15.       9 C5         -1.2742    2.0637   -0.2972 C.ar    1  <1>         0.0000
  16.      10 C6         -0.0433    2.7147   -0.2877 C.ar    1  <1>         0.0000
  17.      11 H2          0.0100    3.7739   -0.5053 H       1  <1>         0.0000
  18.      12 C7         -3.6093    0.2349    1.0134 C.2     1  <1>         0.0000
  19.      13 C8         -4.7130   -0.6979    0.6501 C.ar    1  <1>         0.0000
  20.      14 C9         -4.3260   -1.4370   -0.4687 C.ar    1  <1>         0.0000
  21.      15 C10        -2.9568   -1.0109   -0.8739 C.2     1  <1>         0.0000
  22.      16 C11        -5.1577   -2.3965   -1.0285 C.ar    1  <1>         0.0000
  23.      17 C12        -6.4066   -2.5953   -0.4273 C.ar    1  <1>         0.0000
  24.      18 C13        -6.7946   -1.8544    0.6968 C.ar    1  <1>         0.0000
  25.      19 C14        -5.9467   -0.8901    1.2555 C.ar    1  <1>         0.0000
  26. @<TRIPOS>BOND
  27.      1     1     8    1
  28.      2     1    12    1
  29.      3     1    15    1
  30.      4     2    12    2
  31.      5     3    15    2
  32.      6     4     5   ar
  33.      7     4    10   ar
  34.      8     4    25    1
  35.      9     5     6   ar
  36.     10     5    26    1
  37.     11     6     7    1
  38.     12     6     8   ar
  39.     13     8     9   ar
  40.     14     9    10   ar
  41.     15     9    24    1
  42.     16    10    11    1
  43.     17    12    13    1
  44.     18    13    14   ar
  45.     19    13    19   ar

复制代码



a2.file 文件内容如下:

  1.   -0.309305
  2.   -0.432702
  3.   -0.434797
  4.   -0.249059
  5.    0.618289
  6.   -0.529368
  7.    0.222346
  8.    0.422481
  9.   -0.220411
  10.    0.124004
  11.    0.103999
  12.    0.473956
  13.   -0.008814
  14.   -0.145117
  15.    0.533233
  16.   -0.035198
  17.   -0.130710
  18.   -0.084157
  19.   -0.104420
复制代码


要求:
把a2.file中的内容按行对应的形式放到a1.file文件的 0.0000处,即a2.file中每一行对应a1.file中每一行的0.0000,同时删除0.0000。
注: 文件a1.file中0.0000那一列数据原排列整齐,在论坛上显示时上下的对应位置错开了,请按排列整齐的方式。而且<1>  和0.0000之间是有空格的。

请高手帮帮忙,个人能力实在有限,惭愧 :thank
发表于 2005-12-12 10:54:50 | 显示全部楼层
  1. cat a1.file | sed -n '/^[0-9] /s/0\.0\+//gp' | paste - a2.file
复制代码
try this. It only print out the matching lines, after this, you will need to paste it back to the file. A solution but not the ideal one.
回复 支持 反对

使用道具 举报

发表于 2005-12-12 11:01:40 | 显示全部楼层
你可以手工把a1.file中要进行替换的行分离到另一个文件中吗?
比如保存为a3.file如下:
1 N1 -2.5973 0.0125 0.0420 N.am 1 <1> 0.0000
2 O1 -3.5374 1.0156 1.9351 O.2 1 <1> 0.0000
3 O2 -2.2592 -1.4277 -1.7714 O.2 1 <1> 0.0000
4 C1 1.1189 2.0075 0.0131 C.ar 1 <1> 0.0000
5 C2 1.0694 0.6283 0.2742 C.ar 1 <1> 0.0000
6 C3 -0.1779 0.0020 0.2786 C.ar 1 <1> 0.0000
7 H1 -0.2337 -1.0620 0.4801 H 1 <1> 0.0000
8 C4 -1.3566 0.6994 0.0155 C.ar 1 <1> 0.0000
9 C5 -1.2742 2.0637 -0.2972 C.ar 1 <1> 0.0000

那么这样就可以了:

  1. #awk '{getline $9<"a2.file"; print}' a3.file
复制代码

功能就是把a3.file中的第9列替换为a2.file中的内容...
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-12-12 12:55:30 | 显示全部楼层
Post by yongjian
  1. cat a1.file | sed -n '/^[0-9] /s/0\.0\+//gp' | paste - a2.file
复制代码
try this. It only print out the matching lines, after this, you will need to paste it back to the file. A solution but not the ideal one.


To yongjian:
  先谢谢你的回复。你给的语句我的理解是:把文件a1.file中关于0.0000的所有行用空格代替,然后把文件a2.file粘贴到此处。
  问题1:当我运行此语句时,仅cat a2.file起作用,a2.file的内容显示在当前屏幕。
  问题2:paste命令能够将a2.file粘贴到前面删除的那些数据的位置上吗?起这个作用的命令我未查到。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-12-12 13:07:56 | 显示全部楼层
Post by kayue
你可以手工把a1.file中要进行替换的行分离到另一个文件中吗?
比如保存为a3.file如下:
1 N1 -2.5973 0.0125 0.0420 N.am 1 <1> 0.0000
2 O1 -3.5374 1.0156 1.9351 O.2 1 <1> 0.0000
3 O2 -2.2592 -1.4277 -1.7714 O.2 1 <1> 0.0000
4 C1 1.1189 2.0075 0.0131 C.ar 1 <1> 0.0000
5 C2 1.0694 0.6283 0.2742 C.ar 1 <1> 0.0000
6 C3 -0.1779 0.0020 0.2786 C.ar 1 <1> 0.0000
7 H1 -0.2337 -1.0620 0.4801 H 1 <1> 0.0000
8 C4 -1.3566 0.6994 0.0155 C.ar 1 <1> 0.0000
9 C5 -1.2742 2.0637 -0.2972 C.ar 1 <1> 0.0000

那么这样就可以了:

  1. #awk '{getline $9<"a2.file"; print}' a3.file
复制代码

功能就是把a3.file中的第9列替换为a2.file中的内容...


To kayue:
  先谢谢:) 你给的语句是将从a1.file中提取与a2.file对应的行,然后再合并。用此语句操作那些数据行完全没有问题。 但是,我需要的最后文件不仅仅是这些数据,而且还要包括a1.file中前面7行的内容,中间的数据行(你已提出方法修改),和数据后面的很多行(我在此没有列出)。因为这是文件格式的需要,数据行前后的内容不能去掉。所以请你再看看能否解决此问题?
回复 支持 反对

使用道具 举报

发表于 2005-12-12 15:25:13 | 显示全部楼层
数据是一一对应的吧,直接用sed可不可以?
回复 支持 反对

使用道具 举报

发表于 2005-12-12 15:43:59 | 显示全部楼层
按你要求修改了一-下,该方法可以直接指定a1.file文件中要替换的行的范围,
比如下面指定替换8--16行的内容
  1. #awk '{if (NR>7&&NR<17){getline $9<"a2.file";print} else print}' a1.file
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-12-12 19:23:10 | 显示全部楼层
Post by kayue
按你要求修改了一-下,该方法可以直接指定a1.file文件中要替换的行的范围,
比如下面指定替换8--16行的内容

  1. #awk '{if (NR>7&&NR<17){getline $9<"a2.file";print} else print}' a1.file
复制代码


谢谢kayue!离成功又近了一步:)
采用你给的语句执行单个文件时可以,但我需要转换一系列的文件,在每个a1.file中均是从第8行开始进行数据行的编辑,然而需编辑的中间数据行的结束行数却不同,于是我通过变量来指定每个a2.file文件的行数。此变量行数如何运用到你给的语句中呢?

比如下面脚本的一部分: a2.file指 B$dir.charge; 行数变量为 tmp$dir; a1.file为tmp2.B$dir.mol2


  1. set number=(`cat B$dir.charge|wc -l`)
  2. echo $number+8| bc > tmp$dir
  3. awk '{if (NR>7&&NR<tmp$dir){getline $9<"B$dir.charge";print} else print}' tmp2.B$dir.mol2 >B$dir.mol2
复制代码


本以为通过你们的示范可以试着完成此脚本,但awk的用法我还很陌生,只好又拜托帮忙了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-12-12 21:03:18 | 显示全部楼层
看了一些说明,试着改了一下,还是不行,如下:

  1. set number=(`cat charge_B$dir|wc -l`)
  2. echo $number+8| bc > tmp_$dir
  3. awk  '{if (NR>7&&NR<'tmp_$dir'){getline $9<"'charge_B$dir'";print} else print}' "tmp2_B$dir" >tmp3_B$dir
复制代码


怎么解决呢?
回复 支持 反对

使用道具 举报

发表于 2005-12-12 21:35:37 | 显示全部楼层
可以考虑下面这两个方法:
1 如你所说,只是在awk内部引用外部变量要加单引号,我稍作修改,你看可以不?
你应该要注意下变量的表示,比如B$dir.charge,谁知道dir是变量,还是dir.charge
是变量??亦或是dir.c??应该用大括号括起来,这样可读性好,也不容易出错。


  1. number=`cat B${dir}.charge|wc -l`
  2. number=`expr $number + 8 `
  3. awk '{if (NR>7&&NR<'$number'){getline $9<"'B${dir}.charge'";print} else print}' tmp2.B${dir}.mol2 >B${dir}.mol2

复制代码



2 可以不在awk中指定要替换的范围的上界(最大值),如下:

  1. #awk '{if (NR>7){getline $9<"a2.file";print} else print}' a1.file
复制代码

它会自动根据a2.file文件中行数进行替换,如果a2.file所有行都已经在a1.flle中替换,
那么后面的部分就不会再继续进行了,你只要保存每个a1.file中要替换的行数和对应的
a2.file的行数相同就可以了。


另外,注意,使用脚本批量进行处理时最好先备份下原来数据,除非你确认脚本完全没错,
否则数据一般较难恢复回来。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表