![如何查找所有类型的文件并将它们移动到 {another_dir}/{dir_files_are_at}/{file}?](https://linux22.com/image/118780/%E5%A6%82%E4%BD%95%E6%9F%A5%E6%89%BE%E6%89%80%E6%9C%89%E7%B1%BB%E5%9E%8B%E7%9A%84%E6%96%87%E4%BB%B6%E5%B9%B6%E5%B0%86%E5%AE%83%E4%BB%AC%E7%A7%BB%E5%8A%A8%E5%88%B0%20%7Banother_dir%7D%2F%7Bdir_files_are_at%7D%2F%7Bfile%7D%EF%BC%9F.png)
我有一堆目录,其中有一堆文件和一个文本文件。看起来像这样
MainDir
|------dir1
| |-------file1
| |-------file2
| |-------file3.txt
|------dir17
| |-------file23
| |-------file34
| |-------file52.txt
| |-------file65
每个目录中的文件数量是随机的,只有 1 个或没有 txt 文件。
我需要将所有 txt 文件移动到 MainDir 内的“txtFiles”目录,并且每个 txt 文件都需要位于与其来源目录同名的子目录中(txtFiles 目录中的子目录不存在,因此需要创建它们) 。这就是它应该看起来的样子
MainDir
|------dir1
| |-------file1
| |-------file2
|------dir17
| |-------file23
| |-------file34
| |-------file65
|------txtFiles
| |-------dir1
| | |-------file3.txt
| |-------dir17
| | |-------file52.txt
有没有办法用一个 find 命令来完成它?
另外一些文件和目录名称中也有空格!
答案1
$ tree
.
`-- MainDir
|-- dir1
| |-- notes.txt
| |-- some_file-1
| |-- some_file-2
| `-- some_file-3
`-- dir17
|-- README.txt
|-- some_file-1
|-- some_file-2
`-- some_file-3
3 directories, 8 files
使用rsync
:
$ rsync -a --include '*.txt' --exclude '*/*' MainDir/ MainDir/txtFiles/
$ tree
.
`-- MainDir
|-- dir1
| |-- notes.txt
| |-- some_file-1
| |-- some_file-2
| `-- some_file-3
|-- dir17
| |-- README.txt
| |-- some_file-1
| |-- some_file-2
| `-- some_file-3
`-- txtFiles
|-- dir1
| `-- notes.txt
`-- dir17
`-- README.txt
6 directories, 10 files
该命令用于--include '*.txt'
包含所有带有.txt
文件名后缀的文件,并--exclude '*/*'
排除其他文件。通过使用-a
或--archive
,将在目标中创建源层次结构中被复制部分的副本。
再次运行此命令将导致MainDir/txtFiles/txtFiles
创建一个空目录。在调用中添加-m
or可以避免这种情况。--prune-empty-dirs
rsync
使用find
(从内部MainDir
):
$ find . -type f -name '*.txt' ! -path '*/txtFiles/*' \
-exec sh -c 'for n; do
d="txtFiles/${n%/*}";
mkdir -p "$d" && cp "$n" "$d"
done' sh {} +
这将查找名称匹配*.txt
且不在txtFiles
目录中的所有常规文件。
对于每个找到的文件名路径,将在其下创建路径的目录部分txtFiles
并将文件复制到此处。
rsync
该方法与此方法之间的唯一区别是rsync
,可以复制与给定名称匹配的非常规文件(名为管道的目录等),并且该find
命令必须从内部运行MainDir
。