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.