简体   繁体   English

如何复制目录名称包含字符串的目录

[英]How to copy directories where the directory name contains a string

I'd like to pull out any directories where the directory name contains certain strings (people's names!).我想提取目录名称包含某些字符串(人名!)的任何目录。 Specifically in this case Rob\\ G or Marwa \\E .特别是在这种情况下Rob\\ GMarwa \\E

I've read around and can see how to do this for filenames that are within a list specified in a spreadsheet using this:我已经阅读并可以看到如何使用以下命令对电子表格中指定的列表中的文件名执行此操作:

mkdir -p destination_folder || exit 1
while IFS= read -r name; do
    find . -path ./destination_folder -prune -o \
        -type f -name "$name" -exec cp {} destination_folder \;
done <filenames.txt

But I can't work out how to make it work for copying whole directories.但我不知道如何使它适用于复制整个目录。 Here's a truncated version of the file directory tree I'm looking in. Any help much appreciated!这是我正在查看的文件目录树的截断版本。非常感谢任何帮助!

$ tree -L 3
.
|-- 2020
|   |-- 10\ October
|   |   |-- Aiyin
|   |   |-- Rob\ G
|   |   |-- Yada
|   |   |-- Yavuz
|   |   |-- Ying\ H
|   |   `-- sophie
|   `-- 9\ September
|       `-- Nacho
`-- 2021
    |-- 1\ January
    |   |-- Agnes
    |   |-- Marwa\ E
    |   |-- Ilaria\ M
    |   |-- Sameer\ Bahal
    |   |-- Sandra\ C
    |   |-- Xin
    |   `-- Yada
    |-- 10\ October
    |   |-- Aiyin
    |   |-- Alba
    |   |-- Marwa\ E
    |   |-- Xin
    |   |-- Ying
    |   `-- Rob\ G
    |-- 7\ July
    |   |-- Aakash\ M
    |   |-- Aiyin
    |   |-- Rob\ G
    |`--|-- Alexia

Instead of redirecting the file that contains the names to the command, parse the names.txt-file using echo and sed (to escape the backslashes) , like so:不是将包含名称的文件重定向到命令,而是使用 echo 和 sed (以转义反斜杠)解析 names.txt 文件,如下所示:

mkdir -p destination_folder || exit 1

echo "$(sed 's/\\/\\\\/g' names.txt)" | while IFS= read -r name; do
    find . -type d -name "$name" -exec cp -r {} destination_folder \;
done

Other additions are the -r flag to cp , so that it copies directories and their contents recursively.其他添加是cp-r标志,以便它递归地复制目录及其内容。

Also, find a directory with -type d flag.另外, find一个带有-type d标志的目录。

Your names.txt must contain the exact name of the folder you are after, each folder on their own line.您的names.txt必须包含您要names.txt的文件夹的确切名称,每个文件夹都在自己的行上。 As per your example, if you want to copy the contents of Rob\\ G and Marwa\\ E , your names.txt should be:根据你的例子,如果你想复制Rob\\ GMarwa\\ E ,你的names.txt应该是:

Rob\ G
Marwa\ E

Now bear in mind that this will copy all the files in such folders over to destination_folder/NAME .现在请记住,这会将此类文件夹中的所有文件复制到destination_folder/NAME If you have two identically named folders, which contain identically named files, the previous file will be overwritten!如果您有两个同名文件夹,其中包含同名文件,则之前的文件将被覆盖! (For example if ./2020/10\\ October/Rob\\ G and ./2021/7\\ July/Rob\\ G both contain a file called exam.txt , only one exam.txt will remain in the destination) (例如,如果./2020/10\\ October/Rob\\ G./2021/7\\ July/Rob\\ G都包含名为exam.txt的文件,则只有一个exam.txt将保留在目标中)

If this is a concern, you could try adding some ordering or renaming functionality with the -exec action.如果这是一个问题,您可以尝试使用-exec操作添加一些排序或重命名功能。

This might help:这可能有帮助:

I have used locate to find the files and folders with the specific name.我使用locate来查找具有特定名称的文件和文件夹。 Please note if you do not have locate on your system use the following command sudo apt install mlocate请注意,如果您的系统上没有locate ,请使用以下命令sudo apt install mlocate

locate Rob > name.txt

Here Rob is the folder name we are searching for and we have saved all the possibilities in a text file with the 'name.txt'.这里 Rob 是我们正在搜索的文件夹名称,我们已将所有可能性保存在一个带有“name.txt”的文本文件中。

grep -wi "Rob" name.txt

Using grep command we are searching for Rob in name.txt.使用 grep 命令,我们在 name.txt 中搜索 Rob。 Here -w is to find exact word and i is to find for upper and lower case possiblities.这里-w是查找确切的单词,而i是查找大小写的可能性。

I have used the grep for filtering your pattern.我已经使用grep来过滤你的模式。 This script will copy the directories that contain此脚本将复制包含的目录

anyword with \\ space anyletter/

and copy all that directories to destination并将所有目录复制到destination

#!/bin/bash
paths=($(ls -d $PWD/*/*/*/ | grep -- '[a-zA-Z]*\\ [A-Z]/'))
j=0
len=${#paths[@]}
while [[ $j -lt $len ]]
do
    echo ${paths[$j]} ${paths[$j+1]}
    cp -r "${paths[$j]} ${paths[$j+1]}" /path/to/destination/
    j=$(($j+2))
done

You can also use your pattern by simply modifying the grep command您还可以通过简单地修改 grep 命令来使用您的模式

paths=($(ls -d $PWD/*/*/*/ | grep -- 'Rob\\ G/'))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM