免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 2765 | 回复: 23

[文本处理] (已解决) 请问怎样检查多个文件是否含特定内容,然后删除某些特殊行并输出文件名? [复制链接]

论坛徽章:
0
发表于 2017-06-28 06:08 |显示全部楼层
本帖最后由 greaterwei 于 2017-07-06 20:53 编辑

比如我有多个文件
a1.cif
a2.cif
...
z8.cif
z9.cif


每个文件都含有如下内容:
...
_atom_site_fract_x
_atom_site_fract_y
_atom_site_fract_z
...
...


(1) 要先检查文件内容是否含特别符号"*" 或者 "?", 有的话删除所在行; (2) 然后检查每个文件蓝色区域 (也就是_atom_site_fract_z  这一行的下面区域至文档结束) 有无大写字母”H”;
(3) 最后按文件的读取顺序输出文件列表Report,其中在有"*" 或者 "?"的文件名后增加”+C”,不含H 的文件后增加”+H


例如Report内容可能是:
a1.cif
a2.cif+C
...
z8.cif+H
z9.cif+C+H


z9.cif 的内容是
_atom_site_fract_x
_atom_site_fract_y
_atom_site_fract_z
N 3 4 5
? 12 1
#END

则输出的文件名就是  a9.cif+C+H
文件内容变成了
_atom_site_fract_x
_atom_site_fract_y
_atom_site_fract_z
N 3 4 5
#END



不好意思,小白基本不懂,问题比较多,十分感谢!
谢谢!

论坛徽章:
39
辰龙
日期:2013-08-21 15:45:192015亚冠之广州富力
日期:2015-05-12 16:34:52亥猪
日期:2015-03-03 17:22:00申猴
日期:2015-03-03 17:21:37未羊
日期:2014-10-10 13:45:41戌狗
日期:2014-06-17 09:53:29巨蟹座
日期:2014-06-12 23:17:17双鱼座
日期:2014-06-10 12:42:44寅虎
日期:2014-06-09 12:52:172015亚冠之卡尔希纳萨夫
日期:2015-05-24 15:24:35黄金圣斗士
日期:2015-12-02 17:25:0815-16赛季CBA联赛之吉林
日期:2017-06-24 16:43:52
发表于 2017-06-28 10:16 |显示全部楼层
本帖最后由 关阴月飞 于 2017-06-28 17:42 编辑

for file in /urpath/urfiles*
do
        a=""
       grep -qP '\*|\?' "$file" && { a="+C"; sed -ri  '/\*|\?/d'  "$file"; }
       sed -n  '/_atom_site_fract_z/,$p'  "$file" | grep -q  'H' ||  a+="+H"
       echo ${file}${a} >>/urpath/report.txt
done

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
发表于 2017-06-28 11:35 |显示全部楼层
本帖最后由 sunzhiguolu 于 2017-06-28 20:46 编辑
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my ($sign, $H);
  5. foreach my $path(@ARGV){
  6.     ($sign, $H, my $ok, my $text) = ((0) x 3, '');
  7.     open(my $FHr, '<', $path);
  8.     while(<$FHr>){
  9.         if(/[*?]/){
  10.             $sign ||= 1;
  11.             next;
  12.         }
  13.         $text .= $_;
  14.         if(/_atom_site_fract_z/){
  15.             $ok = 1;
  16.             next;
  17.         }
  18.         if($ok){
  19.             if(m/\A#END/){
  20.                 $ok = 0;
  21.             }else{
  22.                 $H ||= 1 if(/H/);
  23.             }
  24.         }
  25.     }
  26.     close($FHr);
  27.    
  28.     next if($H > $sign);
  29.     my ($fn, $ext) = split(/\./, $path);
  30.     $fn .= '+C' if($sign);
  31.     $fn .= '+H' if(!$H);
  32.    
  33.     unless($H or $sign){
  34.         print("$fn.$ext\n");
  35.         next;
  36.     }
  37.    
  38.     open(my $FHw, '>', $path);
  39.     select($FHw);
  40.     print($text);
  41.     close($FHw);
  42.     select(STDOUT);
  43.    
  44.     print("$fn.$ext\n");
  45. }
复制代码

head -n10 *.cif
==> z1.cif <==
_atom_site_fract_x
_atom_site_fract_y
_atom_site_fract_z
N 3 4 5
#END
Except-H

==> z6.cif <==
_atom_site_fract_x
_atom_site_fract_y
_atom_site_fract_z
N 3 4 5
N 3 4 5H
? 12 1
#END

==> z9.cif <==
_atom_site_fract_x
_atom_site_fract_y
_atom_site_fract_z
N 3 4 5
? 12 1
#END

perl abc.pl z1.cif z6.cif z9.cif
------------------------------------------
z1+H.cif
z6+C.cif
z9+C+H.cif

head -n10 *.cif
==> z1.cif <==
_atom_site_fract_x
_atom_site_fract_y
_atom_site_fract_z
N 3 4 5
#END
Except-H

==> z6.cif <==
0_atom_site_fract_x
_atom_site_fract_y
_atom_site_fract_z
N 3 4 5
N 3 4 5H
#END

==> z9.cif <==
0_atom_site_fract_x
_atom_site_fract_y
_atom_site_fract_z
N 3 4 5
#END

论坛徽章:
0
发表于 2017-06-28 17:34 |显示全部楼层
回复 2# 关阴月飞
谢谢前辈的帮助。我用了您的代码进行了测试,发现特殊符号行可以删除掉,但是"H"检查不了,所有的文件名都加了+H。您能帮忙检查下哪出问题了么,谢谢!

论坛徽章:
39
辰龙
日期:2013-08-21 15:45:192015亚冠之广州富力
日期:2015-05-12 16:34:52亥猪
日期:2015-03-03 17:22:00申猴
日期:2015-03-03 17:21:37未羊
日期:2014-10-10 13:45:41戌狗
日期:2014-06-17 09:53:29巨蟹座
日期:2014-06-12 23:17:17双鱼座
日期:2014-06-10 12:42:44寅虎
日期:2014-06-09 12:52:172015亚冠之卡尔希纳萨夫
日期:2015-05-24 15:24:35黄金圣斗士
日期:2015-12-02 17:25:0815-16赛季CBA联赛之吉林
日期:2017-06-24 16:43:52
发表于 2017-06-28 17:43 |显示全部楼层
回复 4# greaterwei
关键字还是要自己注意一下呀,我多打了个空格进去:

sed -n  '/_atom_site_fract_z /,$p'  "$file" | grep -q  'H' ||  a+="+H"
==》

sed -n  '/_atom_site_fract_z/,$p'  "$file" | grep -q  'H' ||  a+="+H"  

论坛徽章:
0
发表于 2017-06-28 18:02 |显示全部楼层
本帖最后由 greaterwei 于 2017-06-28 18:04 编辑

回复 3# sunzhiguolu

谢谢您的帮助,您的代码逐个是可行的,但是我有几千个文件。所以我用 perl abc.pl *.cif > report.txt
但是report.text里的内容是:
z1+H.cif
z9+H.cif


也就是不能输出去掉特殊符号的文件名。

哪里出问题了呢?
十分感谢!

论坛徽章:
0
发表于 2017-06-28 18:13 |显示全部楼层
回复 5# 关阴月飞

太感谢您了,的确是这个原因,测试成功。
再次感谢!



论坛徽章:
0
发表于 2017-06-28 18:38 |显示全部楼层
本帖最后由 greaterwei 于 2017-06-28 18:51 编辑

回复 5# 关阴月飞

再次感谢!

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
发表于 2017-06-28 18:55 |显示全部楼层
本帖最后由 sunzhiguolu 于 2017-06-28 19:08 编辑

回复 6# greaterwei
按照规则,Report.txt 中应该以什么样的格式保存数据?
以我的那3个文件为例,输出结果是什么?能否提供一个示例?

则输出的文件名就是  a9.cif+C+H
是这个原因吗?


论坛徽章:
0
发表于 2017-06-28 19:28 |显示全部楼层
回复 9# sunzhiguolu

您好,谢谢您详细的回复。

以您的那3个文件为例,perl abc.pl *.cif 输出的结果就是
z1+H.cif
z9+H.cif

少了一个文件
谢谢!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP