我正在从事网站迁移工作。我有一个网站的截图,其中包含您在 URL 中看到的所有文件和目录结构。我想提取所有图像,维护目录结构,并将它们复制到新位置。
例如,如果我有
/content1/index.php
/content1/page2.php
/content1/images/image1.jpg
/content1/images/image2.jpg
/content1/background/spacer.gif
/content1/background/background.gif
/content2/index.php
/content2/images/image3.jpg
/content2/background/spacer.gif
/content2/background/background.gif
那我想要
/content1/images/image1.jpg
/content1/images/image2.jpg
/content1/background/spacer.gif
/content1/background/background.gif
/content2/images/image3.jpg
/content2/background/spacer.gif
/content2/background/background.gif
我可以使用该find
命令获取仅图像文件的列表,但我不知道如何操作每个文件,同时保留其目录路径。
我可以复制整个目录,然后递归删除任何非图像文件,但现在我已经在自己面前设置了这个问题,我认为知道如何去做是值得的,以防万一我真的需要这样做以后就这样吧。
答案1
尝试这个命令(find
和cp
选项--parent
):
find /source -regextype posix-extended -regex '.*(gif|jpg)' \
-exec cp --parents {} /dest \; -print
答案2
使用帕克斯(或其前身 cpio 或 tar 之一)处于复制模式。告诉它只复制所需的文件(.jpg
或.gif
)。语法有点迂回:-s
选项指定如何重命名文件;将文件重命名为空名称意味着它不会被复制,并且由于第一个匹配适用,因此要排除大多数文件,技巧是重命名要包含在其自身中的文件,并排除其余文件。目录不会以这种方式复制,但如果 pax 复制foo/bar/qux.jpg
,则如有必要,它将在目标上创建foo
和,并且 pax 即使在排除的目录内也会递归。foo/bar
pax -rw -pp -s '!\.gif$!&!' -s '!\.jpg$!&!' -s '!.*!!' /content* /destination
您还可以使用 rsync 来执行复制,但它比较笨拙。由于 rsync 不复制排除的目录,因此您需要包含所有目录并随后删除空目录,或者生成要复制的目录列表。看这个答案以获得解释。
rsync -a --include='*.gif' --include='*.jpg' --include='*/' \
--exclude='*' /content* /destination
答案3
假设我们想要将所有 *.conf 文件从 /etc/ 复制到 /tmp/ 我应该这样做:
tar c $(find /etc/ -name '*.conf') | tar xv -C /tmp
怎么运行的:
- 创建要通过正确复制的文件列表
$(find ...)
tar c
创建新的 tar 存档并将其传递到 stdout|
通过管道将存档传输到另一个 tar 进程以解包tar xv
从标准输入读取详细提取存档,但目录更改为/tmp
(目标)。
此方法无法正确处理包含空格的文件。要解决这个问题,您可以生成文件列表并通过 -T 选项传递第一个 tar 命令。
答案4
答案相同,但适用于 Mac,因为--parents
不适用于cp
Mac。
find /source/dir -type f \( -iname "*.jpg" -o -iname "*.png" -o -iname "*.jpeg" \) -exec rsync -R {} ../destination/dir \;