Description
Suppose the file structure under the directory /tmp/gsl
is like following shows(notice that not all sub-directory has Makefile, for example ./block
):
.
|-- INSTALL
|-- Makefile
|-- NEWS
|-- ...
|-- blas
| |-- ChangeLog
| |-- Makefile
| |-- TODO
| |-- blas.c
| |-- ...
|-- block
| |-- ChangeLog
| |-- block.c
|-- bspline
| |-- Makefile
| |-- ...
|-- ...
There are many Makefile
in different sub-directories and we want to copy those Makefile
to home/usrname/gsl
. And the result should be like this:
.
|-- Makefile
|-- blas
| |-- Makefile
|-- bspline
| |-- Makefile
|-- ...
Question
- if the target directory already have necessary parent folder for Makefile, like blas, bspline, how to copy?
- if the target directory don’t have necessary parent folder for Makefile, like blas, bspline, how to copy?
Answer only for question 1
cd /tmp/gsl
# use `find` to find out those file;
# use `sed` to substitute directory name:
# ':' used as substitution delimiter, '&' represent previous matched string -- i.e. whole file path, '\1' as matched content in '()' -- i.e. the directory structure of Makefile;
# and finally use `bash` to execute copy.
find . -name 'Makefile' | sed 's:\(.*\)/Makefile:cp & /home/username/gsl/\1 :' | bash -s
Answer for question 1 & 2
simpler and cleaner.
use --parents
flag to create necessary directory for copy.
–parents
Form the name of each destination file by appending to the target
directory a slash and the specified name of the source file. The
last argument given tocp
must be the name of an existing
directory. For example, the command:
cp --parents a/b/c existing_dir
copies the filea/b/c
toexisting_dir/a/b/c
, creating any
missing intermediate directories.
cd /tmp/gsl/
# the usage of `xargs -i` is much like for each file path of Makefile, `{}` represent the file path
find . -name 'Makefile' | xargs -i cp --parents {} /home/usrname/gsl/
复制特定文件及其相关文件结构
假设当前Linux系统的目录/tmp/gsl下的文件结构如下图所示,其中有很多Makefile分散在各个子目录下(但并非每个子目录都存在Makefile,例如block目录下就没有)。
.
|-- INSTALL
|-- Makefile
|-- NEWS
|-- ...
|-- blas
| |-- ChangeLog
| |-- Makefile
| |-- TODO
| |-- blas.c
| |-- ...
|-- block
| |-- ChangeLog
| |-- block.c
|-- bspline
| |-- Makefile
| |-- ...
|-- ...
要求将这些Makefile拷贝到目录/home/usrname/gsl的对应子目录下,使得拷贝后/home/usrname/gsl下的文件如下图所示:
.
|-- Makefile
|-- blas
| |-- Makefile
|-- bspline
| |-- Makefile
|-- ...
问题一:
假设/home/usrname/gsl下已经存在blas,bspline等子目录,如何实现?
问题二:
假设/home/usrname/gsl下不存在blas,bspline等子目录,如何实现?
问题1的答案
cd /tmp/gsl
# 使用 `find` 找出Makefile的路径;
# 使用 `sed` 替换路径:
# ':' 作为替换分割符, '&' 代表整个匹配度字符串-- i.e. 整个文件路径, '\1' 代表'()'匹配内容 -- i.e. Makefile路径前缀;
# 最后使用 `bash` 来执行复制.
find . -name 'Makefile' | sed 's:\(.*\)/Makefile:cp & /home/username/gsl/\1 :' | bash -s
问题1 & 2的答案
使用 --parents
flag 来创建需要的父目录.
--parents
Form the name of each destination file by appending to the target
directory a slash and the specified name of the source file. The
last argument given tocp
must be the name of an existing
directory. For example, the command:
cp --parents a/b/c existing_dir
copies the filea/b/c
toexisting_dir/a/b/c
, creating any
missing intermediate directories.
cd /tmp/gsl/
# `xargs -i` 就像对Makefile的文件路径集合进行循环操作, 而`{}`就像循环变量,代表每一个不同的路径
find . -name 'Makefile' | xargs -i cp --parents {} /home/usrname/gsl/
Ref
Written with StackEdit.
评论
发表评论