如果您想要 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
.