如果您需要 80 个文件为一组,最好确保名称是可排序的;这就是为什么经常使用前导零的原因。假设文件名中只有一个下划线,名称中没有换行符,那么:
SOURCE="/path/to/dir"
TARGET="/path/to/other/directory"
(
cd $SOURCE || exit 1
ls |
sort -t _ -k2,2n |
awk -v target="$TARGET" \
'{ file[n++] = $1
if (n >= 80)
{
printf "cat"
for (i = 0; i < 80; i++)
printf(" %s", file[i]
printf(" >%s/%s.%.2d\n", target, "newfile", ++number)
n = 0
}
END {
if (n > 0)
{
printf "cat"
for (i = 0; i < n; i++)
printf(" %s", file[i]
printf(" >%s/%s.%.2d\n", target, "newfile", ++number)
}
}' |
sh -x
)
指定了两个目录(文件在哪里以及摘要应该放在哪里);该命令将目录更改为源目录(800 个文件所在的位置)。它列出了名称(如果需要,您可以指定一个 glob 模式)并按数字对它们进行排序。输出被馈送到awk,它会即时生成一个shell脚本。它一次收集 80 个名称,然后生成一个 cat 命令,将这些文件复制到单个目标文件,例如 "newfile.01";调整printf() 命令以适应您自己的命名/编号约定。然后将 shell 命令传递给 shell 执行。
在测试时,将 sh -x 替换为空,或 sh -vn 或类似的东西。仅当您确定它会执行您想要的操作时才添加活动外壳。请记住,shell 脚本在运行时位于源目录中。
从表面上看,xargs 命令会很好用;困难在于协调输出文件编号。可能有一种方法可以使用-n 80 选项来一次对 80 个文件进行分组,还可以通过一些奇特的方式来生成调用编号,但我不知道。
另一种选择是使用xargs -n 执行一个shell 脚本,该脚本可以通过列出目标目录中已有的内容来推断正确的输出文件编号。这在许多方面会更干净:
SOURCE="/path/to/dir"
TARGET="/path/to/other/directory"
(
cd $SOURCE || exit 1
ls |
sort -t _ -k2,2n |
xargs -n 80 cpfiles "$TARGET"
)
cpfiles 的样子:
TARGET="$1"
shift
if [ $# -gt 0 ]
then
old=$(ls -r newfile.?? | sed -n -e 's/newfile\.//p; 1q')
new=$(printf "%.2d" $((old + 1)))
cat "$@" > "$TARGET/newfile. $new
fi
零参数测试避免了xargs 使用零参数执行命令一次的麻烦。总的来说,我更喜欢这个解决方案而不是使用 awk 的解决方案。