简体   繁体   中英

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 .

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:

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.

Also, find a directory with -type d flag.

Your names.txt must contain the exact name of the folder you are after, each folder on their own line. As per your example, if you want to copy the contents of Rob\\ G and Marwa\\ E , your names.txt should be:

Rob\ G
Marwa\ E

Now bear in mind that this will copy all the files in such folders over to 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)

If this is a concern, you could try adding some ordering or renaming functionality with the -exec action.

This might help:

I have used locate to find the files and folders with the specific name. Please note if you do not have locate on your system use the following command 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'.

grep -wi "Rob" name.txt

Using grep command we are searching for Rob in name.txt. Here -w is to find exact word and i is to find for upper and lower case possiblities.

I have used the grep for filtering your pattern. This script will copy the directories that contain

anyword with \\ space anyletter/

and copy all that directories to 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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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