首页 > 解决方案 > 如何按组将多个文件的内容附加到多个文件中

问题描述

我需要通过仅连接同一组文件的内容来输出许多不同的特定于组的文本文件。每个组内要连接的文件内容的顺序很关键,必须按所示进行维护。具体来说,我有这些文件(开发的玩具大小的示例;真实的大尺寸):

$ 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 的内存。相反,我宁愿一次只处理一个组:只连接我的排序命令识别的文件组,然后继续下一个组。

感谢您的想法。

标签: bashfileconcatenationgrouping

解决方案


怎么样:

#!/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)

说明:

任务可以分为两个步骤:

  1. 从文件名中提取组名
  2. 查找属于每个组的文件

第一步在片段中执行:

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 和子字符串来提取组名称。在文件名中。
  • sortuniq通过删除冗余名称来清理组名称。

然后将上面的输出while作为第二步传递给循环:

  • IFS临时分配给换行符以从find
  • 然后数组files保存属于当前处理组的文件名。

建议提前使用一小部分文件进行测试。此外,最好考虑存储连接文件的位置。与现有文件相同的目录可能不是一个好位置。
希望这可以帮助。


推荐阅读