免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 11154 | 回复: 11
打印 上一主题 下一主题

[文本处理] 有2个问题要请大大们帮帮忙 [复制链接]

论坛徽章:
2
15-16赛季CBA联赛之四川
日期:2020-08-18 20:19:4815-16赛季CBA联赛之青岛
日期:2022-01-19 11:51:49
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2020-08-18 12:36 |只看该作者 |倒序浏览
本帖最后由 unix520 于 2020-08-18 20:28 编辑

要强制加3个好友任务才得以发言,这过程非常煎熬,很多人不愿意,或者会忽略掉,或者看不到。在此先谢谢那些加我好友的朋友哈。


吃完饭回来忙着发,
有2个问题要来这请大拿们解决,问题如下:

问题1:在文件夹1放上几个文本,在文件夹2也放几个文本
执行
cd D:/1/

ls *.txt >b

while read i; do awk 'NR==FNR{a[$0];next} !($0 in a)' "$i" D:/2/*.txt ; done < b

我想使用这个awk命令将文件夹1的所有文本与文件夹2的所有文本循环做个对比,如果文件夹2含有文件夹1的内容就删除,但是我套用这个awk命令时写不出处理文件循环利用问题,即完成后的文件以什么方式存储,以便下一次循环可以直接利用它来做对比,不用再一次产生临时文件后再来做对比,这样就得以节省很多时间。


问题2:和上面那个命令需求一样


但是写法有点bug,对比处理后有些重复行无法删除bug,重复行仍然存在文件中,但是这个命令每一次都会产生临时文件,效率不太理想
这个想改写好能够得到正确输出,和改善效率问题
水平有限没法修好,只得来麻烦大佬们了帮忙解决一下,


在文件夹1放上几个文本,在文件夹2也放几个文本
执行
cd D:/1/

ls *.txt >b

while read i; do perl -i.bak -lane 'BEGIN{$F=$ARGV[0]}{if($ARGV eq $F){$h{$_}=1;print}else{if(!$h{$_}){print $_}}}' "$i" D:/1/*.txt; done < b


核心问题就是,如果文件夹1里的文本1与文件夹2里的文本内容相同,就删除文件夹2的,意思就是去重复行
最后非常感谢大大们




论坛徽章:
0
2 [报告]
发表于 2020-08-18 17:36 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
2
15-16赛季CBA联赛之四川
日期:2020-08-18 20:19:4815-16赛季CBA联赛之青岛
日期:2022-01-19 11:51:49
3 [报告]
发表于 2020-08-19 10:11 |只看该作者
本帖最后由 unix520 于 2020-08-19 14:26 编辑

例如:文件夹1里面有多个文本
1.txt
0
2
32.txt
4
5
1
6
3.txt
7
8
9
文件夹2里也有多个文本
1a.txt
1
a

2a.txt
2
b
0
3a.txt
3
c3

循环去重复后得到文件2各个结哥
1a.txt
a
2a.txt
b
3a.txt
c3


论坛徽章:
2
15-16赛季CBA联赛之四川
日期:2020-08-18 20:19:4815-16赛季CBA联赛之青岛
日期:2022-01-19 11:51:49
4 [报告]
发表于 2020-08-19 18:25 |只看该作者
不重新编辑了,编辑一次就要重新审核一次的

上面1.txt向下数等4行前后拼接了
32.txt
应该是
3
2.txt

论坛徽章:
0
5 [报告]
发表于 2020-08-20 23:19 |只看该作者
  1. [root@vh122 awk]# tree /mnt/awk
  2. /mnt/awk
  3. ├── folder1
  4. │   ├── 1.txt
  5. │   ├── 2.txt
  6. │   └── 3.txt
  7. ├── folder2
  8. │   ├── 1a.txt
  9. │   ├── 2a.txt
  10. │   └── 3a.txt
  11. └── test.awk

  12. /mnt/awk/test.awk
  13. #!/usr/bin/awk -f

  14. BEGIN{
  15.   path1="/mnt/awk/folder1"
  16.   path2="/mnt/awk/folder2"
  17.   cmd1=sprintf("cat `ls %s/*.txt`",path1)
  18.   while(cmd1|getline > 0)
  19.     f1[$0]
  20.   while("ls "path2|getline file > 0){
  21.     j=0
  22.     cmd2=sprintf("cat %s/%s",path2,file)
  23.     while(cmd2|getline > 0){
  24.       if(!($0 in f1))
  25.         f2[++j]=$0
  26.     }
  27.     cmd3=sprintf("> %s/%s",path2,file)
  28.     system(cmd3)
  29.     for(i=0;++i<=length(f2);){
  30.       cmd4=sprintf("echo %s >> %s/%s",f2[i],path2,file)
  31.       system(cmd4)
  32.     }
  33.     delete f2
  34.   }  
  35. }
复制代码

论坛徽章:
2
15-16赛季CBA联赛之四川
日期:2020-08-18 20:19:4815-16赛季CBA联赛之青岛
日期:2022-01-19 11:51:49
6 [报告]
发表于 2020-08-21 13:24 |只看该作者
回复 5# jzsjm1002

看起来好复杂,如何执行它?

论坛徽章:
2
15-16赛季CBA联赛之四川
日期:2020-08-18 20:19:4815-16赛季CBA联赛之青岛
日期:2022-01-19 11:51:49
7 [报告]
发表于 2020-08-21 13:45 |只看该作者


按你步骑路径执行
返回这个

论坛徽章:
2
15-16赛季CBA联赛之四川
日期:2020-08-18 20:19:4815-16赛季CBA联赛之青岛
日期:2022-01-19 11:51:49
8 [报告]
发表于 2020-08-21 20:15 |只看该作者
回复 5# jzsjm1002
谢谢,
修好我自己路径后可以,看起来效率比上面那些命令要慢很多,另外似乎循环不够完全(即要先拿1文件夹中的每一本去比对,删除文件夹2下的所有文本重复行)。重复行似乎删除不够完整,目前还没找到问题所在

希望有更快更准确写法出来,,,

论坛徽章:
2
15-16赛季CBA联赛之四川
日期:2020-08-18 20:19:4815-16赛季CBA联赛之青岛
日期:2022-01-19 11:51:49
9 [报告]
发表于 2020-08-22 15:07 |只看该作者
我不知道为什么要写得那么复杂
事实上,拿文件夹1里所有文本和文件夹2里所有文本比对删除,如果发现在文件夹2存在,就删除。

过程,
cd 文件夹1
ls *txt > 1
得到文件夹1里面所有文本,然后拿第一本去和文件夹2里面所有文本比对,如果相同,就删除文件夹2里面重复行

第一本做完,到第二本,又到第三个,直到做完文件夹1任务。

最大问题是要考虑文件夹2输出定向,在下一次循环时无法直接使用

论坛徽章:
29
程序设计版块每日发帖之星
日期:2016-02-29 06:20:0015-16赛季CBA联赛之天津
日期:2016-08-10 10:33:1115-16赛季CBA联赛之深圳
日期:2016-08-17 15:07:2015-16赛季CBA联赛之佛山
日期:2016-11-07 11:33:5015-16赛季CBA联赛之广夏
日期:2016-11-15 09:13:31CU十四周年纪念徽章
日期:2016-11-24 14:12:25极客徽章
日期:2016-12-07 14:03:4015-16赛季CBA联赛之深圳
日期:2016-12-07 17:15:2715-16赛季CBA联赛之北京
日期:2016-12-22 09:30:0115-16赛季CBA联赛之深圳
日期:2016-12-22 10:49:2115-16赛季CBA联赛之山西
日期:2017-02-10 09:05:3215-16赛季CBA联赛之同曦
日期:2017-02-27 14:19:08
10 [报告]
发表于 2020-09-20 09:10 |只看该作者
你这个是自己玩还是处理问题呀, 数据量大不大
你的思路是: 拿过滤文件夹下的N文件依次去处理待过滤文件夹下的M个文件, 共要处理N*M次,这过程中前N-1次循环每次都要生成M个逐级过滤的中间文件,现在你问题在这里是吧

所以我感觉你文件是不是比较大呀, 可不可以先将过滤文件夹下的N个文件先整到一个总文件: cat dir1/* >> filter_src, 然后在去处理过滤  awk 'NR==FNR{a[$0]++;next}!a[$0]{print > FILENAME".ok"}' filter_src dir2/*

或者grep 呢, 先grep出每个文件对应的在filter_src 出现的filte**件,然后再来一次
for filr in `ls dir2`; do grep -xf filter_src dir2/$file > tmp/$file; done
for file in `ls tmp`; do grep -xvf tmp/$file dir2/$file > dir2/$file."ok"; done
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP