Linux:对每个复制的文件执行命令

Linux:对每个复制的文件执行命令

在对每个复制的文件执行命令时,将文件复制到新位置的最佳方法是什么?复制的文件夹应该有子目录。

例如,您可能正在执行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"/{} \;

(注意:--referencePOSIX 不要求)。

或者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 很慢,但它允许您做几乎任何事情。

相关内容