LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (https://www.linuxquestions.org/questions/linux-general-1/)
-   -   mv with exclusion of FULL PATH ? (https://www.linuxquestions.org/questions/linux-general-1/mv-with-exclusion-of-full-path-4175499648/)

czezz 03-27-2014 05:44 AM

mv with exclusion of FULL PATH ?
 
This is a simple structure of dirs and files where I want to present my problem:
Code:

/testing/backup/1.txt
/testing/backup/2.txt
/testing/backup/3.txt
/testing/backup/test_file
/testing/tmp
/testing/1.txt
/testing/2.txt
/testing/.hidden_file

I would like to:
1. move (mv) all content of /testing to /testing/tmp
2. exclude /testing/1.txt but /testing/backup/1.txt must be included.

I was trying some tricks with FIND and exclusion like this -type f ! \( -name 1.txt\) but then it excluded both /testing/1.txt but /testing/backup/1.txt. It is also not possible to add to this exclusion full path.
Does anyone have some smart idea how to do that move with full path exclusion ?

Temporary my solution for this issue is rsync:
Code:

rsync /testing/* -a --exclude /test/1.txt /testing/tmp

smallpond 03-28-2014 01:52 PM

Won't that get you /testing/tmp/tmp/tmp/tmp ...?

colucix 03-28-2014 04:34 PM

The switches to specify full path are -path and -wholename (less portable). I assume that you want to move the whole directory structure into tmp (except tmp itself) otherwise you will end up with some files overwritten by others with the same name (e.g. 2.txt). In this case you may use the option -maxdepth to limit the search to the first level of the directory tree.

Here is an example:
Code:

$ find /testing -maxdepth 1 ! -path /testing/1.txt
/testing
/testing/.hidden_file
/testing/backup
/testing/tmp
/testing/2.txt

However we still need to exclude the /testing directory itself and the /testing/tmp directory. The latter to avoid the annoying error message from mv that reminds we cannot move a directory to a sub-directory of itself. Here we go:
Code:

$ find /testing -mindepth 1 -maxdepth 1 ! -path /testing/1.txt ! -path /testing/tmp
/testing/.hidden_file
/testing/backup
/testing/2.txt

Hope this helps.

czezz 03-31-2014 04:57 AM

Hi, thank you for your answer. That worked perfectly and solved my problem, thanks :)
That is full command that I used.
Code:

find /testing -mindepth 1 -maxdepth 1 ! -path /testing/1.txt ! -path /testing/tmp -exec mv {} /testing/tmp \
I also tried to play a little bit with this command and I see is it easy to adjust it to different scenarios.
Eg. to skip file: /testing/backup/1.txt
So, I modified command like this:
Code:

find /testing -mindepth 1 -maxdepth 1 ! -path /testing/backup/1.txt ! -path /testing/tmp -exec mv {} /testing/tmp \;
find /testing -mindepth 1 -maxdepth 2 ! -path /testing/backup/1.txt ! -path /testing/tmp -exec mv {} /testing/tmp \;

but it failed...
dir /testing/tmp has not been moved (thats good) but /testing/backup/1.txt has been moved.
Why is that ?.



UPDATE:
and it is odd because by issuing this I have a good output:
Code:

find /testing -mindepth 1 -maxdepth 2 ! -path /testing/backup/1.txt ! -path /testing/tmp
/testing/2.txt
/testing/.hidden_file
/testing/1.txt
/testing/backup
/testing/backup/2.txt
/testing/backup/test_file
/testing/passwd_link

... but it does not work with mv command.


UPDATE #2
I think I know why. Its probably because of this:
Code:

find /testing -mindepth 1 -maxdepth 2 ! -path /testing/backup/1.txt ! -path /testing/tmp
/testing/2.txt
/testing/.hidden_file
/testing/1.txt
/testing/backup
/testing/backup/2.txt
/testing/backup/test_file
/testing/passwd_link

...and if Im right its quite tricky to make it working now

colucix 03-31-2014 07:02 AM

This is because from your output
Code:

/testing/2.txt
/testing/.hidden_file
/testing/1.txt
/testing/backup
/testing/backup/2.txt
/testing/backup/test_file
/testing/passwd_link

the backup directory (highlighted in red) is moved recursively into tmp, and all the files inside it are moved accordingly without exclusion. At this point the command line would become far more complicate and not mnemonic, hence I suggest as alternative the command rsync, for example:
Code:

rsync -av --dry-run --remove-source-files --exclude tmp --exclude backup/1.txt /testing/ /testing/tmp
Some notes:
  • the --dry-run is for testing purposes: rsync will only list the file to copy without actually copy them. If the list is ok for you, run it again without this option.
  • the --remove-source-files deletes the original file after the transfer, so use it if you're absolutely sure of the results from the --dry-run above.
  • The slash at the end of the source path /testing/ is mandatory to copy the content of the /testing directory (hidden files included) and not the directory /testing itself.
Hope this helps.

czezz 03-31-2014 09:11 AM

Professor Colucix, your help is priceless. As always :)
Now I also better understand your explanation for -maxdepth
Thank you.

ps. I think it should be --remove-sent-files instead of --remove-source-files


All times are GMT -5. The time now is 06:08 AM.