使用 Mac OS X 终端将选择的文件夹复制到新位置,并具有合并行为

Con*_*oob 2 bash grep terminal.app macos

我有一个文件夹“foo”,其中包含很多子文件夹,例如

foo
 |---20101
 |---20102
 |---20103
 |---20111
 |---20112
 |---20113
Run Code Online (Sandbox Code Playgroud)

还有更多的方式,但希望它能解释这个场景。我现在想将此文件夹中以“2011”开头的所有文件夹复制到名为“bar”的“foo”的同级中。但是,'bar' 已经包含一些同名的文件夹

bar
 |---20111
 |---20113
 |---20114
Run Code Online (Sandbox Code Playgroud)

源文件夹和目标文件夹的内容应该合并。请注意,该脚本还需要创建一个 bar/20112 文件夹,因为该文件夹不存在。

我是 Mac 终端脚本的新手,并已成功地 grep 正确的文件夹

foo>ls | grep ^2011 
Run Code Online (Sandbox Code Playgroud)

其中列出了正确的文件夹,但我不知道如何将其传递给适当的复制操作。

ter*_*don 7

复制命令是cp. 如果你给它-r(递归)标志,它会做你想要的,它会将文件复制到现有文件夹中,并在目标文件夹丢失时创建新文件夹。

但是,您永远不应该解析 的输出ls,您应该使用find或者更简单的bash globbing

cp -rv foo/2011* bar/
Run Code Online (Sandbox Code Playgroud)

如果存在名称以 开头的文件和文件夹2011,请使用find它的-exec选项,该选项会将您提供的任何命令应用于由find(称为{})找到的所有内容:

find foo/ -type d -name "2011*" -exec cp -rv '{}' bar/ \;
Run Code Online (Sandbox Code Playgroud)

在这种特定情况下,没有理由保存命令的输出并将其传递给cp. 这有时是必要的,所以这里是它的完成方式。一般来说,一个命令的输出可以作为另一个命令的输入,如果放在倒置的逗号或$().

cp -rv `find foo/ -type d -name "2011*"` bar/
Run Code Online (Sandbox Code Playgroud)

或者

cp -rv $(find foo/ -type d -name "2011*") bar/
Run Code Online (Sandbox Code Playgroud)

或者,您可以遍历结果:

for dir in $(find foo/ -type d -name "2011*"); do cp -rv "$dir" bar/; done
Run Code Online (Sandbox Code Playgroud)

如果您的文件/文件夹名称可以包含特殊字符或新行等,这会变得更加复杂,在这种情况下,您应该执行以下操作:

find foo/ -type d -name "2011*" | while IFS= read -r dir; do 
       cp -rv "$dir" bar/; 
done
Run Code Online (Sandbox Code Playgroud)