我想做的是复制字典范围内的文件。
文件示例:
-rw-r--r-- 1 root root 15276 Oct 5 2004 a2ps.cfg
-rw-r--r-- 1 root root 2562 Oct 5 2004 a2ps-site.cfg
-rw-r--r-- 4 root root 4096 Feb 2 2007 acpi.txt
-rw-r--r-- 1 root root 48 Feb 8 2008 adjtime.jpg
-rw-r--r-- 4 root root 4096 Feb 2 2007 alchemist.jpg
使用示例:
- 将 3 个文件从
asps.cfg
复制到acpi.txt
- 将 3 个文件从
a2ps-site.cfg
复制到adjtime.jpg
- 将 4 个文件从
a2ps-site.cfg
复制到alchemist.jpg
那么有没有办法将一系列文件(从文件名 X 到文件名 Y)复制到一个目录中?
喜欢:cp filenameX ... filenameY destination/
答案1
通用方法是定义一个打印一系列文件名的 shell 函数。此函数的简单版本将列出当前目录中两个文件名之间的所有文件:
range()
{
ls | sed -n "/^$1\$/,/^$2\$/p"
}
这使用 sed 范围来打印两个给定字符串 ($1
和$2
) 之间的任何内容。
然后您可以在cp(1)
命令中使用此函数:
cp $(range asps.cfg acpi.txt) /destination/path
如果文件名中含有空格,此操作将会失败。为此,你需要变得更复杂一些:
range asps.cfg acpi.txt | xargs -d '\n' -I {} cp {} /destination/path
如果您的文件名中包含换行符 (\n),则该操作将会失败。这是不太可能的,所以解决这个问题留给读者作为练习。
您可以将其一起放入另一个 shell 函数中:
cprange()
{
[ $# -eq 3 ] || { echo "usage: cprange start end dir" >&2; return 1;}
range "$1" "$2" | xargs -d '\n' -I {} cp {} "$3"
}
并像这样使用它:
cprange filenameX filenameY destination
请记住,范围仅适用于当前目录中的文件名。您可以通过多种方式对此进行扩展(向 附加目录参数range
、从参数中提取路径到range
usingdirname
等),但我将根据您的要求将其留给您。请在此询问您是否需要更多详细信息。
答案2
Zsh 有一种简单的方法可以从 glob 结果中选择一系列文件(glob 是通配符匹配)。从好的方面来说,该命令编写起来很短。在减号站点上,您必须计算出要写入的文件的序号。例如,以下命令复制.jpg
当前目录中第 21 个、第 22 个、…、第 40 个扩展名的文件,文件按字母顺序枚举:
cp *.jpg([21,40]) destination/
Zsh 有一个选项可能对您有帮助,也可能没有帮助:under setopt numeric_glob_sort
, foo9bar.jpg
will be sorted before foo10bar.jpg
。您还可以在 glob 限定符中选择不同的排序顺序,例如cp *.jpg(om[21,40]) destination/
选择第 21 到 40 个最近的文件(使用大写字母O
以相反的顺序排序)。看全局限定符在手册中了解更多信息。
在任何 shell 下,您都可以编写一个循环来迭代文件,从要写入的第一个文件开始复制,并在最后一个文件后停止。警告,未经测试。
in_range=
for x in *.jpg; do
if [ "$x" = "first-file.jpg" ]; then in_range=1; fi
if [ -n "$in_range" ]; then cp "$x" destination/; fi
if [ "$x" = "last-file.jpg" ]; then break; fi
done
答案3
此示例中最简单的是使用 M-* 来完成您的模式并删除您不想复制的模式。
% cp *[hit Escape and press *]
->
% cp file1 file2 file3 file4 ...
然后手动删除您不想复制的文件。无论如何,这是一个 shell 功能,而不是cp
的。
您可以根据需要完善该模式。如果目录中有许多其他文件,并且您只想复制以 开头的文件a
,则只需以该字母开始模式即可。您可能需要查找有关文件名通配的 shell 文档。例如,http://tldp.org/LDP/abs/html/globbingref.html。
答案4
看起来文件名已排序,并且您似乎以相同的数量分发。
将所有文件名保存到一个文件中
ls > all_files
将文件分成批次
split -l 4 all_files all_files-
现在每个文件中有 4 个文件名,all_files-*
选择一个,说出all_files-aa
并做你的副本:
xargs -I{} cp {} folder_for_batch_1 < all_files-aa