2017-01-13 46 views
0

我想连接其遵循特定名称模式,即文件特定的命名模式(UNIX)我有很多文件,如:连接文件与

nameX_4_1.txt 
nameX_983_2.txt 
nameX_5_1.txt 
nameX_2_2.txt 
nameY_7_1.txt 
nameY_4_2.txt 
nameY_8_1.txt 
nameY_3_2.txt 
nameY_9_1.txt 
nameY_6_2.txt 
. 
. 
. 

...我要永远串联文件,它们具有相同的“名称”?和相同的最后一个数字(1或2),即从上面的例子中文件来连接

"nameX_4_1.txt" and "nameX_5_1.txt" 
"nameX_983_2.txt" and "nameX_2_2.txt" 
"nameY_7_1.txt" and "nameY_8_1.txt" and "nameY_9_1.txt" 
"nameY_4_2.txt" and "nameY_3_2.txt" and "nameY_6_2.txt" 
. 
. 
. 

我第一次尝试写像的脚本:

for f1 in *_?_1.txt 
do 
f2="${f1%%_?_1.txt}_?_2.txt" 
. 
. 
. 

...但我relized(作为一个完整的unix新手),这不是如何获得其他匹配文件的名称,以便所选名称的文件可以在循环中连接... 我会感谢任何提示(优先使用unix命令但我实际上打开任何其他解决方案)。谢谢!

+0

连接文件的名称应该是什么? – Inian

回答

0

这里是编辑!

首先,对于以前的错误感到抱歉。我不知道最近有什么进入我的。

其次,问题并未指定如何连接文件。

如果使用Unix标记它,你想要做的外壳(猛砸例如),那么,这将得到你想要的东西:

#! /bin/bash 

for file in $(ls ./name*1.txt) 
do 
    echo $file 
done 

这将打印出所有文件(每个一个行)通过通配符进行过滤(名称中使用'*')。 您将不得不使用read命令或cat来使用大量的管道来连接名称将在$ file变量中的文件的内容。

如果你有很多文件,这将有点不切实际。它仍然可以工作,但对你的系统很粗鲁。

因此,我建议你使用一些真正的脚本语言来实现你想要的一个过程。 这里是用Python一个完整的例子:

#! /usr/bin/env python 
import glob 

namepattern = "./name*1.txt" 
outputfile = "./output.txt" 
whole_text = "" 
for x in glob.iglob(namepattern): 
    f = open(x, "r") 
    whole_text += "\n"+f.read() 
    f.close() 
f = open(outputfile, "w") 
f.write(whole_text) 
f.close() 

如果你想确保串联加排序前)您的文件进行排序(用于循环:

for x in sorted(glob.iglob(...)): ... 

这虽然会串连唯一一个组文件,由namepattern变量指定。所以你将不得不几次运行这个脚本。关于如何将它们分组的想法之一在这里由hansaplast展示。

+0

你应该说这是python – hansaplast

+0

这甚至与这个问题有什么关系?这是一个没有任何解释的随机代码片段;它处于不同的(未指定的)编程语言中;它不能解决问题。 – melpomene

+0

对不起!以某种方式在标签中看到Python。很好,我要编辑! – Dalen

0

当你打开这里的任何编程语言是一个Python的解决方案:

import os 
from collections import defaultdict 

buckets = defaultdict(list) 

for filename in os.listdir('files/'): 
    parts = filename.split('.')[0]('_') 
    # group by string before first _ and number after last _ 
    # "nameX_4_1.txt" becomes ("nameX", "1") 
    key = (parts[0], parts[-1]) 
    buckets[key].append(filename) 

# files are now grouped, output them (order is not predictable) 
for key,value in buckets.items(): 
    print(", ".join(value)) 

样品会话:

$ ls files/ 
nameX_2_2.txt nameX_5_1.txt nameY_3_2.txt nameY_6_2.txt nameY_8_1.txt 
nameX_4_1.txt nameX_983_2.txt nameY_4_2.txt nameY_7_1.txt nameY_9_1.txt 

$ python script.py 
nameX_2_2.txt, nameX_983_2.txt 
nameY_3_2.txt, nameY_4_2.txt, nameY_6_2.txt 
nameY_7_1.txt, nameY_8_1.txt, nameY_9_1.txt 
nameX_4_1.txt, nameX_5_1.txt 

Python程序预期安装文件是files/所以你需要将其更改为实际的目录。

如果您想了解更多关于python程序的功能或错过任何功能的信息,请发表评论。

0

为起点,你可以试试这个(庆典):

for xy in X Y; do 
    for s12 in 1 2; do 
    echo " $xy --- $s12" 
    for file in $(ls name${xy}_*_$s12.txt); do 
     echo "file $file" 
    done 
    done 
done 

注意第一echo线:各组的文件前打印。您可以选择(准备)写入临时文件,或者构建稍后执行的命令,而不是使用这个echo。对于临时文件,而不是echo file $file,你会做cat $file >> my_temporary_file,或类似的东西。

0

问题看起来有点毛茸茸的,所以我可能会用perl,没有壳(警告,未经测试的代码):

#!/usr/bin/env perl 
use strict; 
use warnings; 

my %groups; 

for my $file (glob '*_*_[12].txt') { 
    my $key = $file; 
    $key =~ s/_[^_]*(?=_\d\.txt\z)/_X/ or die "No match for $key"; 
    push @{$groups{$key}}, $file; 
} 

for my $group (values %groups) { 
    print "@$group\n"; 
} 

的想法是遍历匹配*_*_[12].txt所有文件和计算归一键为每个名字;例如foobar_123_1.txt将变成foobar_X_1.txt(我们用X替换最后两个下划线之间的部分)。

这样,您想要连接的所有文件都按同一个键组合在一起。最后,我们简单地遍历所有组,然后在每个组中输出文件名(用空格分隔),然后输出换行符。