dir1,dir2,dir3,dir4
我在 Linux 机器上有多个目录 { }。
每个目录中都有多个文件(具有相同的扩展名,例如 .zip),我想将它们备份到相应的目录 { dir1-bck,dir2-bck,dir3-bck,dir4-bck
}。我不需要备份整个文件夹,只需备份每个文件夹中的几个文件即可。
我该如何将复制的文件放入dir1/*.zip
...dir1-bck
以获取提供的目录列表。我目前正在使用:
cp -r src/dir1/*.zip dest/dir1-bck/
cp -r src/dir2/*.zip dest/dir2-bck/
cp -r src/dir3/*.zip dest/dir3-bck/
cp -r src/dir4/*.zip dest/dir4-bck/
虽然这可行,但仍有很大的改进空间。
查看xargs
手册页和论坛上的类似帖子,我觉得这是完成这项工作的工具,但我似乎无法正确使用它。
答案1
循环可能for
就够了。具体形式取决于这些目录的命名方式。可以是:
cd src || exit 1
for d in "dir"{1..4}; do
cp -r "$d"/*.zip "../dest/$d-bck/"
done
笔记:
src
在( )内工作很好cd src
,因此变量包含一个字符串,无需额外处理即可在目标路径中使用。../
在这种情况下,目标路径通过前置调整,但通常可能像"/full/path/to/dest/$d-bck/"
。- 我引用了,
dir
以防你用空格等替换名称。$d
出于同样的原因,我使用了双引号,更多的。 - 如果
*.zip
是文件则不需要-r
。
或者该for
行可能是:
for d in dir1 dir2 dir3 dir4; do
如果你需要指定几个任意命名的目录,这将很有用。或者甚至:
for d in *; do
可以做出一些改进,例如:
( cd src || exit 1
for d in *; do
dst="../dest/$d-bck/"
[ -d "$d" ] && mkdir -p "$dst" && cp -- "$d"/*.zip "$dst"
done )
改进之处:
- 所有代码都在子 shell (
(…)
) 中运行,因此cd
即使您将代码粘贴到终端中也不会影响当前 shell。如果它必须是独立脚本(执行,而不是获取),那么子 shell 就无关紧要了。 - 我们检查是否
$d
是一个目录。 - 我们尝试创建目标目录(以防它不存在)。
cp
仅当目标目录存在时,我们才会继续。- 我们用双破折号
$d
以破折号开头的情况。
可能出现的问题:
"$d"/*.zip
可能会扩展到太多项目(Argument list too long
)。您的原始命令同样存在“缺陷”。如果“每个目录中只有几个文件”,那么这应该不是问题。"$d"/*.zip
可能不会扩展(*
将保持文字)。这不会造成任何损害,但目标目录仍将预先创建。在这种情况下,可能需要额外的逻辑来抑制目录创建。- 整个代码片段的退出状态仅取决于最后一个
[ … && mkdir … && cp …
。您需要额外的逻辑来使早期的问题影响退出状态。