免费注册 查看新帖 |

ChinaUnix.net

  平台 论坛 博客 文库 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
12下一页
最近访问板块 发新帖
查看: 2088 | 回复: 10

[文本处理] [文本处理]文本合并处理 [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2018-08-21 09:34 来自手机 |显示全部楼层
本帖最后由 volwang 于 2018-08-21 13:52 编辑

好久没来chinaunix,很想念江湖朋友。最近又遇到文本处理的任务,还是请各位江湖高手帮帮忙哦。
输入:
三个文本,数据结构都是两列,
文本1,命名text1:
filename  version
file1   A
file2   B
file3   C
file1   B
..   ..
文本2,命名text2:
filename version
file1  C
file1  D
file2  D
file5  E
....

文本3,命名text3:
filename version
file1  E
file1  F
file2  G
file4 D
file5  R
....
每个文本里,同一文件可能有多个版本
每个文件里,有相同的文件名存在
三文件行数较多,都需要遍历首行,发现相同文件名合并输出
没有版本信息用“/”代替

输出:
文件名    文本1中版本   文本2中版本  文本3中版本
file1             A,B             C,D     E,F
file2                B               D        G
file3               C                /            /
file4                /                /            D
file5                /                E          R
.. ..

多谢。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2018-08-21 09:50 来自手机 |显示全部楼层
三个文件里有相同的文件名存在

论坛徽章:
0
发表于 2018-08-21 11:30 |显示全部楼层
本帖最后由 本友会机友会摄友会 于 2018-08-21 11:36 编辑

我来提供一种,linux版powershell解题方案:
$输出哈希表 = @{}
[hashset]$文件1版本 = @()
$数组 = @($文件1版本,$文件2版本,$文件3版本)
$输出哈希表.add('file1',$数组)

然后遍历3个文件,然后依次插入即可。

你向 $文件1版本 中插入 【版本】时,自动去重。 $文件2版本,$文件3版本 同理。
你向 输出哈希表 中插入 【'file1'】【'file2'】时,自动去重。
if 判断 。当输出哈希表中含有 【'file1'】时,取出数组中的hashset,继续向 $文件1版本 中插入 【版本】

论坛徽章:
0
发表于 2018-08-21 11:30 |显示全部楼层
本帖最后由 本友会机友会摄友会 于 2018-08-21 11:42 编辑

ps第9课:powershell数组(静态,动态)
http://bbs.chinaunix.net/thread-4267455-1-1.html



ps第11课:尽解powershell哈希表
http://bbs.chinaunix.net/thread-4296512-1-1.html

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2018-08-21 12:03 来自手机 |显示全部楼层
@本友会机友会摄友会,谢谢回复,感觉这个方法效率高,但还是不会用。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2018-08-21 15:14 |显示全部楼层
希望朋友们帮看看

论坛徽章:
19
程序设计版块每日发帖之星
日期:2016-05-03 06:20:0015-16赛季CBA联赛之山西
日期:2018-08-07 19:46:2315-16赛季CBA联赛之佛山
日期:2018-08-03 13:19:33黑曼巴
日期:2018-07-06 15:19:5015-16赛季CBA联赛之八一
日期:2018-07-05 10:34:0915-16赛季CBA联赛之八一
日期:2018-07-03 16:56:4615-16赛季CBA联赛之深圳
日期:2018-06-15 14:59:3715-16赛季CBA联赛之青岛
日期:2018-06-08 13:45:2815-16赛季CBA联赛之同曦
日期:2018-06-04 19:42:2015-16赛季CBA联赛之山东
日期:2018-05-30 12:44:59CU十四周年纪念徽章
日期:2018-05-15 11:36:3815-16赛季CBA联赛之广东
日期:2018-05-14 09:52:42
发表于 2018-08-21 16:36 |显示全部楼层
回复 1# volwang


  1. awk 'BEGIN{printf("文件名 文件1版本 文件2版本 文件3版本\n")}FNR>1{a[$1" "FILENAME]=a[$1" "FILENAME]?a[$1" "FILENAME]!~"/"?a[$1" "FILENAME]","$2:$2:$2;for(i=1;i<=3;i++){if(!a[$1" "ARGV[i]]){a[$1" "ARGV[i]]="/"}}}END{for(i in a){split(i,b);c[b[1]]=c[b[1]]?c[b[1]]" "a[i]:a[i]}{for(j in c){print j,c[j]}}}' 1 2 3
复制代码

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2018-08-21 21:16 |显示全部楼层
回复 7# wh7211

谢谢回帖,用前面的文本做输入,能得到输出。
我替换成真实的输入,发现有一行异常数据:
A ,,,,,, / /

然后其他行多乱了,本来是第2列的出现在第2、3、4列。可能是我的文件名格式有关系。能否改良下或者排错。
再次感谢。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2018-08-21 21:25 |显示全部楼层
回复 7# wh7211

期望得到的输出:
文件名    文本1中版本   文本2中版本  文本3中版本
file1             A,B             C,D     E,F
file2                B               D        G
file3               C                /            /
file4                /                /            D
file5                /                E          R
运行你提供的脚本,输出:
文件名    文本1中版本   文本2中版本  文本3中版本
file1             A,B             C,D     E,F
file2                /               D        G
file2              B                 /           /
file3               C                /            /
file4                /                /            D
file5                /                E          R
综上,不应出现2行file2。


论坛徽章:
0
发表于 2018-08-22 13:46 |显示全部楼层
本帖最后由 本友会机友会摄友会 于 2018-08-22 13:52 编辑

  1. #用win记事本,保存为unicode编码。即bom头+utf16le编码。
  2. $输出哈希表 = [Ordered]@{}

  3. $输入文件1路径全名 = 'a:\pscode\0\foreach-hash\text1.txt'
  4. $输入文件1 = Import-Csv -Delimiter ' ' -LiteralPath $输入文件1路径全名
  5. foreach ($每一行 in $输入文件1)
  6. {
  7.     if  ( $输出哈希表.Contains($每一行.filename) )
  8.     {
  9.         [System.Collections.Generic.HashSet[string]]$文件1版本 = $输出哈希表[$每一行.filename][0]
  10.                 $null = $文件1版本.add($每一行.version)
  11.                 $输出哈希表[$每一行.filename][0] = $文件1版本
  12.     }
  13.     else
  14.     {
  15.         [System.Collections.Generic.HashSet[string]]$文件1版本 = @()
  16.                 [System.Collections.Generic.HashSet[string]]$文件2版本 = @()
  17.                 [System.Collections.Generic.HashSet[string]]$文件3版本 = @()
  18.                 $null = $文件1版本.add($每一行.version)
  19.                 $数组 = @($文件1版本,$文件2版本,$文件3版本)
  20.                 $输出哈希表.add($每一行.filename,$数组)
  21.     }
  22. }

  23. $输入文件2路径全名 = 'a:\pscode\0\foreach-hash\text2.txt'
  24. $输入文件2 = Import-Csv -Delimiter ' ' -LiteralPath $输入文件2路径全名
  25. foreach ($每一行 in $输入文件2)
  26. {
  27.     if  ( $输出哈希表.Contains($每一行.filename) )
  28.     {
  29.         [System.Collections.Generic.HashSet[string]]$文件2版本 = $输出哈希表[$每一行.filename][1]
  30.                 $null = $文件2版本.add($每一行.version)
  31.                 $输出哈希表[$每一行.filename][1] = $文件2版本
  32.     }
  33.     else
  34.     {
  35.         [System.Collections.Generic.HashSet[string]]$文件1版本 = @()
  36.                 [System.Collections.Generic.HashSet[string]]$文件2版本 = @()
  37.                 [System.Collections.Generic.HashSet[string]]$文件3版本 = @()
  38.                 $null = $文件2版本.add($每一行.version)
  39.                 $数组 = @($文件1版本,$文件2版本,$文件3版本)
  40.                 $输出哈希表.add($每一行.filename,$数组)
  41.     }
  42. }

  43. $输入文件3路径全名 = 'a:\pscode\0\foreach-hash\text3.txt'
  44. $输入文件3 = Import-Csv -Delimiter ' ' -LiteralPath $输入文件3路径全名
  45. foreach ($每一行 in $输入文件3)
  46. {
  47.     if  ( $输出哈希表.Contains($每一行.filename) )
  48.     {
  49.         [System.Collections.Generic.HashSet[string]]$文件3版本 = $输出哈希表[$每一行.filename][2]
  50.                 $null = $文件3版本.add($每一行.version)
  51.                 $输出哈希表[$每一行.filename][2] = $文件3版本
  52.     }
  53.     else
  54.     {
  55.         [System.Collections.Generic.HashSet[string]]$文件1版本 = @()
  56.                 [System.Collections.Generic.HashSet[string]]$文件2版本 = @()
  57.                 [System.Collections.Generic.HashSet[string]]$文件3版本 = @()
  58.                 $null = $文件3版本.add($每一行.version)
  59.                 $数组 = @($文件1版本,$文件2版本,$文件3版本)
  60.                 $输出哈希表.add($每一行.filename,$数组)
  61.     }
  62. }

  63. $输出文件 = 'a:\pscode\0\foreach-hash\out.csv'
  64. Set-Content -LiteralPath $输出文件 -Encoding Unicode -Value '' -NoNewline
  65. Add-Content -LiteralPath $输出文件 -Encoding Unicode -Value '文件名,文本1中版本,文本2中版本,文本3中版本'

  66. foreach ($temp in $输出哈希表.GetEnumerator())
  67. {
  68.         Add-Content -LiteralPath $输出文件 -Encoding Unicode -Value $($temp.key) -NoNewline
  69.         Add-Content -LiteralPath $输出文件 -Encoding Unicode -Value ',' -NoNewline

  70.         if ($temp.value[0].count -eq 0)
  71.         {
  72.                 Add-Content -LiteralPath $输出文件 -Encoding Unicode -Value '/,' -NoNewline
  73.         }
  74.         else
  75.         {
  76.                 Add-Content -LiteralPath $输出文件 -Encoding Unicode -Value $($temp.value[0]) -NoNewline
  77.                 Add-Content -LiteralPath $输出文件 -Encoding Unicode -Value ',' -NoNewline
  78.         }

  79.         if ($temp.value[1].count -eq 0)
  80.         {
  81.                 Add-Content -LiteralPath $输出文件 -Encoding Unicode -Value '/,' -NoNewline
  82.         }
  83.         else
  84.         {
  85.                 Add-Content -LiteralPath $输出文件 -Encoding Unicode -Value $($temp.value[1]) -NoNewline
  86.                 Add-Content -LiteralPath $输出文件 -Encoding Unicode -Value ',' -NoNewline
  87.         }

  88.         if ($temp.value[2].count -eq 0)
  89.         {
  90.                 Add-Content -LiteralPath $输出文件 -Encoding Unicode -Value '/,'
  91.         }
  92.         else
  93.         {
  94.                 Add-Content -LiteralPath $输出文件 -Encoding Unicode -Value $($temp.value[2]) -NoNewline
  95.                 Add-Content -LiteralPath $输出文件 -Encoding Unicode -Value ','
  96.         }
  97. }
复制代码



这段代码我调试通过。wi