move linux directory unless it already exists - linux

I need a way to move a linux directory and all of it's contents only if it doesn't currently exist in the target location. If it does currently exist (including all sub-folders and files) then the source folder can just can just be removed recursively.
I currently use the following framework but wish to expand it to meet the above criteria.
mv /source/* /target
Thanks

rsync -av --remove-source-files source/ destination/ && rm -rf source/
Replace source/ and destination/ accordingly.
Source

Gnu mv has the -n or --no-clobber option. Unfortunately, it seems to return with an successful exit status even if the mv was a no-op due to the --no-clobber option, however it seems that in your use case, you can simply do the --no-clobber move and then clear the source if the move succeeds regardless of whether or not it did anything.

Related

Copy a directory structure and only touch the copied files

I want to mimic copying a directory structure recursively (as in cp -r or rsync -a), but only touch the copied files, i.e. make all the copied files empty.
The specific use case is for a Snakemake pipeline; Snakemake looks for existing files in order to decide whether to re-run a pipeline step, and I want to make it believe the steps have already been run while avoiding fully downloading all the files.
This is a little kludgy, but you could pipe the output of find or rsync -nv into a little bash loop with mkdir -p and touch:
find /some/dir -type f | while read FILE; do
mkdir -p $(dirname $FILE)
touch $FILE
done

Removing file from folder in linux

Linux os
Hello
i have downloaded the file using wget. the file downloaded with some messy name like
index.html?format=csv&timezone=Asia%2FKolkata&use_labels_for_header=true.
now i am trying to remove this file using rm, but its not getting removed.
Linux os
sudo rm -f Unconfirmed\sudo rm -f Unconfirmed\index.html?format=csv&timezone=Asia%2FKolkata&use_labels_for_header=true
how can i removed it from folder.
It works as below. Make sure you have permission for that file/folder to edit(delete or update). You have used sudo that is correct.
To remove the folder with all its contents(including all interior
folders):
rm -rf /path/to/directory
To remove all the contents of the folder(including all interior folders) but not the folder itself:
rm -rf /path/to/directory/* or
rm -rf /path/to/directory/{*,.*}
if you want to make sure that hidden files/directories are also removed.
To remove all the "files" from inside a folder(not removing interior folders):
rm -f /path/to/directory/{*,.*}
Where:
rm - stands for "remove"
-f - stands for "force" which is helpful when you don't want to be asked/prompted
if you want to remove an archive, for example.
-r - stands for "recursive" which means that you want to go
recursively down every folder and remove everything.
rm -rf "yourfilename" put double quotes over your file name.
Also check if you have permission to delete this file.
make notifies you of the deletion by printing an rm -f command that specifies the file it is deleting.
Eg:
Here MergeSort is the file that I need to remove.

Synchronize content of directories in Linux

Let's assume I have following source directory
source/
subdir1/file1
subdir1/file2
subdir2/file3
subdir3/file4
and target directory
target
subdir1/file5
subdir2/file6
subdir4/file7
I would like to move content of source subdirectories to right target subdirectories so result look like this
target
subdir1/file1
subdir1/file2
subdir1/file5
subdir2/file6
subdir2/file3
subdir3/file4
subdir4/file7
Is there some Linux command to do this or must I write a script myself?
To suimmarize, it is important to move, not copy. That rules out cp and rsync but allows mv. mv, however, has the issue that it is not good at merging the old directory into the new.
In the examples that you gave, the target directory had the complete directory tree but lacked files. If that is the case, try:
cd /source ; find . -type f -exec sh -c 'mv "$1" "/target/$1"' _ {} \;
The above starts by selecting the source as the current directory with cd /source. Next, we use find which is the usual *nix utility for finding files/directories. In this case, give find the -type f option to tell it to look only for files. With the -exec option, we tell it to move any such files found to the target directory.
You have choices for how to deal with conflicts between the two directory trees. You can give mv the -f option and it will overwrite files in the target without asking, or you can give it the -n option and it will never overwrite a target file, or your can give it the -i option and it will ask you each time.
In case the target directory tree is incomplete
If the target directory tree is missing some directories that are in the source, the we have to create them on the fly. This adds just minor complication:
cd /source ; find . -type f -exec sh -c 'mkdir -p "/target/${1%/*}"; mv "$1" "/target/$1"' _ {} \;
The mkdir -p command assures that the directory we want exists before we try to move the file there.
Additional notes
The form ${1%/*} is an example of one of the shells powerful features called "parameter expansion". This particular feature is suffix removal. In general, it looks like ${parameter%word} which tells bash to expand word and remove it from the end of parameter. In our case, the name of the parameter is 1, meaning the first argument to the script. We want to remove the file name and just leave behind the directory that the file is in. So, the word /* tells the shell to remove the last slash and any characters which follow.
The commands above use both single and double quotes. They have to be copied exactly for the command to work properly.
To sync dorectory maybe used rsync
Example:
rsync -avzh source/ target/
More info man rsync
Move (no copy)
rsync --remove-source-files -avzh source/ target/

Copy all files in a directory to a local subdirectory in linux

I have a directory with the following structure:
file_1
file_2
dir_1
dir_2
# etc.
new_subdir
I'd like to make a copy of all the existing files and directories located in this directory in new_subdir. How can I accomplish this via the linux terminal?
This is an old question, but none of the answers seem to work (they cause the destination folder to be copied recursively into itself), so I figured I'd offer up some working examples:
Copy via find -exec:
find . ! -regex '.*/new_subdir' ! -regex '.' -exec cp -r '{}' new_subdir \;
This code uses regex to find all files and directories (in the current directory) which are not new_subdir and copies them into new_subdir. The ! -regex '.' bit is in there to keep the current directory itself from being included. Using find is the most powerful technique I know, but it's long-winded and a bit confusing at times.
Copy with extglob:
cp -r !(new_subdir) new_subdir
If you have extglob enabled for your bash terminal (which is probably the case), then you can use ! to copy all things in the current directory which are not new_subdir into new_subdir.
Copy without extglob:
mv * new_subdir ; cp -r new_subdir/* .
If you don't have extglob and find doesn't appeal to you and you really want to do something hacky, you can move all of the files into the subdirectory, then recursively copy them back to the original directory. Unlike cp which copies the destination folder into itself, mv just throws an error when it tries to move the destination folder inside of itself. (But it successfully moves every other file and folder.)
You mean like
cp -R * new_subdir
?
cp take -R as argument which means recursive (so, copy also directories), * means all files (and directories).
Although * includes new_subdir itself, but cp detects this case and ignores new_subdir (so it doesn't copy it into itself!)
Try something like:
cp -R * /path_to_new_dir/

On Linux, how do I recursively copy files while ignoring certain names?

I need to recursively copy a directory tree, ignoring any subdirectories named 'CVS'. Is there a simple way to do this?
rsync -av --exclude=CVS <src> <dst>
tar -cpf - --exclude=CVS directory | sh -c 'cd /wherever/it/goes && tar -xpf -'
Modify the right-hand tar's options to -xvpf if you'd like to see what's going on.
Why not approach it from a slightly different angle and check out the files from CVS using the export command.
This'll give you the directories without any of the CVS artifacts.

Resources