【问题标题】:How to append contents of multiple files into many files by group如何按组将多个文件的内容附加到多个文件中
【发布时间】:2018-11-18 13:08:55
【问题描述】:

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

$ 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)。因此上面的代码是不正确的,但是像 xargs cat 或 xargs paste 这样的东西可以捕获为每个组发出的文件名,如果我只能从某个 Gnu 程序中获得按组发出的文件名。

我真的需要按组发出的组文件来分类或粘贴,然后对找到的所有组执行此操作。

由于文件数量庞大,磁盘超过 40GB,这只是一个开发示例,我不希望在写入组文件之前尝试将所有文​​件内容加载到工作内存中。我没有 40GB 的内存。相反,我宁愿一次只处理一个组:只连接我的排序命令识别的文件组,然后继续下一个组。

感谢您的想法。

【问题讨论】:

    标签: bash file concatenation grouping


    【解决方案1】:

    比如:

    #!/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%%.*}" 通过删除“。”之后的目录名和子字符串来提取组名。在文件名中。
    • sortuniq 通过删除冗余名称来清理组名称。

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

    • IFS 被临时分配给一个换行符,以从 find 的输出创建一个数组
    • 然后数组files 保存属于当前处理组的文件名。

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

    【讨论】:

    • 有趣的程序。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-05
    • 1970-01-01
    • 2019-04-03
    • 2011-07-27
    相关资源
    最近更新 更多