我需要通过仅串联同一组文件的内容来输出许多不同的特定于组的文本文件。每个组中要串联的文件内容的顺序至关重要,必须按所示进行维护。具体来说,我有这些文件(用于开发的玩具大小示例;用于实际的大量示例):
$ 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个403and780文件进入其1个组文件,依此类推。像403and780这样的组值将作为新创建文件的名称。
所以这是到目前为止我最好的代码。我看着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的RAM。相反,我宁愿一次只处理一个组:仅合并我的排序命令已识别的文件组,然后继续进行下一个组。
感谢创意。
答案 0 :(得分:0)
怎么样?
#!/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%%.*}"
行通过删除目录名和子字符串来提取组名。在文件名中。sort
和uniq
通过删除冗余名称来清理组名称。然后将上面的输出作为第二步传递到while
循环:
IFS
暂时分配给换行符,以根据find
的输出创建一个数组files
保存属于当前处理组的文件名。建议事先对一小部分文件进行测试。另外,最好考虑将链接文件存储在何处。与现有文件相同的目录可能不是一个好的位置。
希望这会有所帮助。