bash - 如何按组将多个文件的内容附加到多个文件中
问题描述
我需要通过仅连接同一组文件的内容来输出许多不同的特定于组的文本文件。每个组内要连接的文件内容的顺序很关键,必须按所示进行维护。具体来说,我有这些文件(开发的玩具大小的示例;真实的大尺寸):
$ find . -name "*.doc" | sort -k1 -k2 -t'.'
./403and780.bunk_2018-02-09.doc
./immortalis.bunk_2018-03-01.doc
./KryptoFreak405.bunk_2018-03-01.doc
./kygiacomo.bunk_2018-02-09.doc
./Mimi108.bunk_2018-03-02.doc
./namohysip.bunk_2018-02-09.doc
./scarletcrawford.bunk_2018-02-10.doc
./SDsc0rch.bunk_2018-02-09.doc
./SDsc0rch.bunk_2018-02-10.doc
./SDsc0rch.bunk_2018-03-02.doc
./shitpostlord4321.bunk_2018-02-09.doc
./thwinks.bunk_2018-03-02.doc
基本上,我希望将 3 个 SDsc0rch 文件的内容按所示顺序放入 1 个组文件中。只有 1 403 和 780 文件类似地进入其 1 组文件等。像 403 和 780 这样的组值将用作新创建文件的名称。
所以这是我迄今为止最好的代码。我查看了 awk 和 datamash,但似乎无法从他们那里获得帮助。
$ find . -name "*.doc" | sort -k1 -k2 -t'.' | xargs cat #(or paste)
$ paste --serial SDsc0rch.bunk_2018-02-09.doc SDsc0rch.bunk_2018-02-10.doc SDsc0rch.bunk_2018-03-02.doc > SDsc0rch.doc
我手工制作了一个模拟粘贴命令,它只适用于一个特定的组 (SDsc0rch)。因此,上面的代码是不正确的,但是如果我只能从某个 Gnu 程序中获得按组发出的文件名,则像 xargs cat 或 xargs paste 这样的东西可以捕获为每个组发出的文件名。
我真的需要按组发出的组文件来分类或粘贴,然后对找到的所有组执行此操作。
由于文件数量庞大,磁盘上超过 40GB,这只是一个开发示例,我不希望在写入组文件之前尝试将所有文件内容加载到工作内存中。我没有 40GB 的内存。相反,我宁愿一次只处理一个组:只连接我的排序命令识别的文件组,然后继续下一个组。
感谢您的想法。
解决方案
怎么样:
#!/bin/bash
while read -r group; do
ifs_bak=$IFS
IFS=$'\n'
declare -a files=( $(find . -name "$group*.doc" | sort -k2 -t".") )
IFS=$ifs_bak
cat "${files[@]}" > "${group}.doc" # or "paste" as you like
done < <(find . -name "*.doc" -print0 | while read -r -d "" file; do
tmp=$(basename "$file"); echo "${tmp%%.*}"
done | sort | uniq)
说明:
任务可以分为两个步骤:
- 从文件名中提取组名
- 查找属于每个组的文件
第一步在片段中执行:
find . -name "*.doc" -print0 | while read -r -d "" file; do
tmp=$(basename "$file"); echo "${tmp%%.*}"
done | sort | uniq
输出:
403and780
KryptoFreak405
Mimi108
SDsc0rch
immortalis
kygiacomo
namohysip
scarletcrawford
shitpostlord4321
thwinks
-print0
处理可能包含空格的文件名是必需的。- 以下行
tmp=$(basename "$file"); echo "${tmp%%.*}"
通过删除“。”之后的 dirname 和子字符串来提取组名称。在文件名中。 sort
并uniq
通过删除冗余名称来清理组名称。
然后将上面的输出while
作为第二步传递给循环:
IFS
临时分配给换行符以从find
- 然后数组
files
保存属于当前处理组的文件名。
建议提前使用一小部分文件进行测试。此外,最好考虑存储连接文件的位置。与现有文件相同的目录可能不是一个好位置。
希望这可以帮助。
推荐阅读
- python-3.x - 对于我的脚本中无法实现的每一行“for循环”
- python - 循环使用 lambda 列并使用其他列的值进行计算
- jprofiler - 监控 JProfiler 的许可证服务器
- vue.js - 如何在vuejs的子组件中将值从prrent传递到方括号
- ios - 从 nib 文件加载视图时出现问题,视图宽度为 0.0
- flutter - 我怎样才能摆脱这种颤振覆盖错误?
- google-apps-script - 如果 string.match() 不匹配,为什么谷歌应用程序脚本的执行被取消?
- c# - 在 Linq 表达式中使用 `.Result` 调用异步方法会导致死锁
- javascript - 将数学运算的结果绑定到 vuejs 中的输入或 div 结果
- python - 无法在 keras(tensorflow) 中使用 model.predict()