在对每个复制的文件执行命令时,将文件复制到新位置的最佳方法是什么?复制的文件夹应该有子目录。
例如,您可能正在执行cp -R
共享或rsync
备份,并且您想要:
- 重新编码视频:
ffmpeg -i $source -c:v libx264 -crf 23 -c:a copy $destination
- 压缩存档:
gzip -9 $source
- 加密传输:
gpg -e -r [email protected] $source
- 仅复制标题以供预览:
head -n 10 $source > $destination
- 甚至链接多个命令
答案1
第一步是复制目录结构:
sdir="/path/to/source/dir"
tdir="/path/to/target/dir"
cd "$sdir"
find . -type d -exec mkdir -p "$tdir"/{} \;
您可能还想做更多的事情,例如复制权限:
find . -type d -exec chmod --reference={} "$tdir"/{} \;
(注意:--reference
POSIX 不要求)。
或者mkdir
你可以使用cp -a --attributes-only
(非 POSIX):
# this assumes $tdir doesn't yet exist but its future parent does
cp -a "$sdir" "$tdir"
然后从中删除所有非目录$tdir
,留下裸目录结构:
# make sure "$tdir" is what it should be
find "$tdir" ! -type d -delete
现在,当您有了目标目录结构时,就可以处理文件了。如果您不需要管道、重定向等,此示例方法即可:
cd "$sdir"
find . -type f -exec ffmpeg -i {} -c:v libx264 -crf 23 -c:a copy "$tdir"/{} \;
# source ^^ target ^^^^^^^^^^
如果你确实需要管道或重定向,你将需要一个 shell 来处理它们:
cd "$sdir"
find . -type f -exec sh -c 'head -n 10 "$1" >"$2"/"$1"' sh-find {} "$tdir" \;
# for sh these are $0:^^^^^^^, $1:^^, $2:^^^^^
为每个文件运行单独的 shell 很慢,但它允许您做几乎任何事情。