我想连接遵循特定名称模式的文件,即我有许多文件,如:
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"
.
.
.
...但我重新(作为一个完整的unix菜鸟)这不是如何获取其他匹配文件的名称的方式,因此所选名称的文件可以循环连接... 我会感谢任何提示(优先使用unix命令但我实际上打开了任何其他解决方案)。谢谢!
答案 0 :(得分:0)
这是编辑!
首先,对不起之前的错误。我不知道最近有什么东西进入了我。
其次,问题没有说明你想如何连接文件。
如果用Unix标记它你想在shell中做(例如Bash),那么,这将得到你想要的东西:
#! /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()
如果要确保在连接之前对文件进行排序,请将sorted()添加到for循环:
for x in sorted(glob.iglob(...)): ...
这只会连接一组由namepattern变量指定的文件。所以你必须运行这个脚本几次。关于如何对它们进行分组的一个想法由hansaplast提供。
答案 1 :(得分: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程序的功能或者您是否遗漏任何功能,请发表评论。
答案 2 :(得分:0)
作为一个起点,你可以尝试这个(bash):
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
,或类似的内容。
答案 3 :(得分:0)
问题看起来有点毛茸茸,所以我可能使用perl,而不是shell(警告,未经测试的代码):
#!/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
替换最后两个下划线之间的部分。)
这样,您要连接的所有文件都在同一个键下组合在一起。最后,我们简单地遍历所有组并输出每个组中的文件名(用空格分隔),然后是换行符。