Copy all directories except one - linux

I'm copying all subdirectories with its contents to my current directory as follows:
cp -r dirToCopy/* .
But in the folder dirToCopy, there is one subfolder called dirNotToCopy which should not be copied.
How can I filter that particular folder out of my expression?

Use extended globbing:
shopt -s extglob
cp -r dirToCopy/!(dirNotToCopy) .

Well if you want to do it in single line:
find /path_to/dirToCopy -mindepth 1 -type d ! -name dirNotToCopy -exec cp -r {} . \;
One more way of doing the same.

find /path_to/dirToCopy -maxdepth 1 -type d ! -name dirNotToCopy -exec cp -r {} . \;
Instead of using mindepth suggested in the other answer, we should use maxdepth.
(I can't comment or edit another answer since I do not have enough reputation yet)
Also note that this command only copies the subdirectories, not the files in the directory.

Related

How to copy list of folders keeping the partial folder structure that of parent directory

Say I want to copy some folders from find /40/AD/GWAS_data/Source_Plink/2021_ADGC_EOAD -name "plink_data*" which has these folders:
/40/AD/GWAS_data/Source_Plink/2021_ADGC_EOAD/ADGC_NHW/ADNI/TOPMEDr2/vcffile/plink_data
/40/AD/GWAS_data/Source_Plink/2021_ADGC_EOAD/ADGC_ASIAN/BIOCARD/TOPMEDr2/vcffile/plink_data
into /40/AD/GWAS_data/Source_Plink/2021_ADGC_EOAD/NEW_DIR/, but I want the new directory to have :
/40/AD/GWAS_data/Source_Plink/2021_ADGC_EOAD/NEW_DIR/ADGC_NHW/ADNI/TOPMEDr2/vcffile/plink_data
/40/AD/GWAS_data/Source_Plink/2021_ADGC_EOAD/NEW_DIR/ADGC_ASIAN/BIOCARD/TOPMEDr2/vcffile/plink_data
I tried this but it copies the whole path: find /40/AD/GWAS_data/Source_Plink/2021_ADGC_EOAD -name "plink_data*" -exec cp --parents {} /target \;
How do I go about doing it? Thanks!
UPDATE: I was able to perform my task with cp using answer from #Cyrus, but not with mv. I thought applying cp and mv in this command would not be any different, but I was wrong. In fact, I needed to use both mv and cp for different tasks, so I resorted to using a loop
for line in $(find . -name "*plink_data*"); do
new_FOLD="$(echo $line| cut -d"." -f2-)"
mkdir -p "NEW_DIR/${new_FOLD}"
cp/mv $line "NEW_DIR/${new_FOLD}"
done
I suggest:
cd /40/AD/GWAS_data/Source_Plink/2021_ADGC_EOAD
mkdir -p NEW_DIR
find . -name "plink_data" -not -path "./NEW_DIR/*" -exec cp --parent {} NEW_DIR \;

problem in copying find results in another directory

I'm trying to execute this command to copy the latest file that exist in the courant directory to another one .
find . -mtime -1 -exec cp -r {} /media/96DB-120D/bck \;
but after copying the recent files , I find the other content of the folder that does not respond to the condition -mtime -1 .
If any one had an idea about how to fix it to just copy the result of find command and thanks.
The find command probably includes the directory and then cp copies all the files in the directory. Add -type f to only have find report actual files.
Try the -p option of cp command which will preserve the timestamp of the copied file:
find . -mtime -1 -exec cp -pr {} /media/96DB-120D/bck \;
I think this is the best solution :
find . -mtime -1 -type f -exec cp --parents {} /media/960DB-120D/db \;

How to find all subdirectories with a specific name and delete its contents (and NOT delete the directories themselves)

I can't seem to find a solution that works within several posts that seem to ask a similar question. This is the command that has come the closest to working which I've used as a test on test folders:
find . -iname "*Adobe Premiere Pro Video Previews*" -exec sh -c 'rm -rf {}/*' \;
The problem is that find . -iname "*Adobe Premiere Pro Video Previews*" by itself finds the subdirectories and prints them while -exec sh -c 'rm -rf {}/*' \; does the job of deleting only the contents without deleting the directory itself. But they do not work to find the directory and delete its contents when put together. What command should I use to accomplish those two tasks simultaneously?
Thanks
for dir in `find . -type d -iname "*Adobe Premiere Pro Video Previews*"`; do
find $dir -type f -delete
done
I may not be an expert in bash, but for me the following command is working :
find . -iname "*test*" -type d -exec sh -c "rm -rf {}/*" \;
#!/bin/bash
while read -r line; do
echo "Deleting CONTENTS of folder: $line"
rm -rf "$line/*"
done <<< $(find . -type d -iname "*Adobe Premiere Pro Video Previews*")
This loops through the results of find (Using -type d to only show directories so you won't run into problems if a file contains the search string) and performs an rm -rf on the contents of each result. The /* is important as without it it would delete the result directory too, instead of just its contents.

How to identify a folder and then decide whether to move it or not in bash

I have a linux issue that I would like some help with...
I have an application that creates directories for me. I'd like to write a script that looks at these directories, checks to see whether the directory starts with a certain string of characters, if it does, leave it alone, if it doesn't then move it...
So, from a logical stance:
If directoryname begins with "ABC" then do nothing
else
move folder to sharedrive
This script will go in the cron.hourly folder so it runs automatically for me.
Any help is greatly appreciated!!!
find . -mindepth 1 -maxdepth 1 -type d ! -name 'ABC*' -exec mv -i {} ./dest \;
If you can identify a simple pattern for the directories you don't want to move, you might even be able to use bash's extglob setting:
shopt -s extglob
mv !(ABC)*/ ./dest/
For such a simple pattern, just use find,
find * -type d ! -name "ABC*" | while read f; do mv $f /tmp/test2; done
You could also use something like this, but it might have problems due to how find does the recursion.
find * -type d ! -name "ABC*" -exec mv {} /tmp/test2 \;
So you could instead just output the list of dirs to a file, and then move them.

Create file in Linux and replace content

I have a project in Linux. I want to create a file named index.html in all folders.
So I have used the following command:
find . -type d -exec touch {}/index.html \;
It's working! Now I'm trying to copy the existing file from a given location and it to be automatically replaced into all the folders of my project.
This should actually work exactly in the same way:
find . -type d -exec cp $sourcedir/index.html {}/index.html \;
If I understand your question correctly, what you want is to copy a given file in all the directories.
You can use a similar find command :
find . -type d -exec cp -f /tmp/index.html {} \;
where /tmp/index.html is path to the original file (replace it with your own path).
Also, you don't need to create the files if your final objective is to replace them with the original file.
tar -cvzf index.tar.gz `find . -type f -iname 'index.html'` && scp index.tar.gz USER#SERVER:/your/projec/root/on/SERVER && ssh USER#SERVER "tar -xvzf index.tar.gz"
Or if you're in the proper directory localhost, and rsync is available:
rsync -r --exclude='**' --include='**/index.html' . USER#SERVER:/your/projec/root/on/SERVER
HTH

Resources