Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

How can I move files up a directory where there might be hundreds or thousands of files in the directory, and you might not be sure about whether there are dupes in ... What method would you use?

How to handle dupes will vary, sometimes we'll overwrite, sometimes we need to be safer. IO can be important because these are production servers. But given quantity a prompt for non duplicate files isn't an option. Preservation of permissions, and timestamps, etc, is important. We usually won't know what the data is.

Oh and it using mv isn't required, rsync, cp solutions welcome.

note: we're running CentOS 5.5 so let me know if it won't work there due to it being a more recent... feature

share|improve this question
    
What would ypu want to do about dupes ? –  Iain Dec 17 '10 at 15:51
    
@Iain depends on the situation? I work at a webhost... it really depends on the mv and whether we care about preservation in the case of... and whether we've already made a backup. This question is fairly open. I'm just looking for good options, and maybe a comment about whether or not it can bite you and how. –  xenoterracide Dec 17 '10 at 15:54
    
I assume there's too many files for the shell to handle mv * ../ or mv -i * ../? –  Michael Mrozek Dec 17 '10 at 15:54
    
@Michael I'm sure it varies... in some cases probably not. In some cases maybe. I'm trying to catch as many options for my work env as possible. –  xenoterracide Dec 17 '10 at 15:58
add comment

7 Answers

up vote 6 down vote accepted

I would recommend using rsync from the parent:

rsync -avPr -b --suffix='-original' child/* .

which will backup all existing duplicate files in parent to file-original.

share|improve this answer
    
I think -a implies -r –  xenoterracide Dec 17 '10 at 17:26
    
@xenoterracide - Right you 'r' –  Tok Dec 17 '10 at 17:42
    
@Tok is it possible to do the copy's as hardlinks? so as not to waste IO. (like -l for cp) –  xenoterracide Dec 18 '10 at 12:13
    
@xenoterracide - You can use the -H or --hard-links flags for rsync to preserve hard links. –  Tok Dec 20 '10 at 14:14
1  
@xenoterracide - You can use the --link-dest=DIR flag to achieve this behavior as: rsync -avP --link-dest=/path/to/src /path/to/src/* /path/to/dest/ which will hard link into dst/ any unchanged files between src and src, in this case all files. Ordinarily you see this flag used when you wish to re-link backup files without copying their data such as --link-dest=/most/recent/backup. –  Tok Dec 20 '10 at 14:46
show 1 more comment

You can try

find . -maxdepth 1 -print0 | xargs -I '{}' -r0 mv '{}' ..

which will overwrite dupe files in ..

You can use mv -u '{}' to not overwrite if the dupe in .. is the same or newer

share|improve this answer
    
why pipe find to xargs? why not use + –  xenoterracide Dec 17 '10 at 16:15
1  
@xenoterracide - Habit and portability (it's a GNU extension). On top of that I've just tried it and can't figure out how to pass the second parameter .. to the mv '{}' + command as the + just adds to the end. –  Iain Dec 17 '10 at 16:31
    
@Iain the + is in POSIX I was actually told previously GNU find was late to get it. –  xenoterracide Dec 17 '10 at 16:46
    
You're right but I still can't figure a way to use the .. –  Iain Dec 17 '10 at 17:04
2  
@xenoterracide: With GNU coreutils: -exec mv -t .. -- {} +. Portably: -exec sh -c 'mv -- "$@"' _ {} +. –  Gilles Dec 17 '10 at 20:04
show 1 more comment

I said on our ML

mv * ..

obviously this isn't very safe... it will overwrite things. It might have limits that I've never run into.

share|improve this answer
2  
If you have a large number of files you'll likely get an 'argument list too long error'. –  Iain Dec 17 '10 at 16:08
2  
It may do bad things if you have a file name that begins with -. It won't catch files whose name begins with .. –  Gilles Dec 17 '10 at 20:06
add comment

In this example will move files from '/parent/old-dir' to '/parent':

cd /parent

rsync -av --progress old-dir/ .

rm -rf old-dir

By rsync rules it will replace dups with newer files from old-dir.

share|improve this answer
add comment

The following is a python template that I have used to good effect in the past.

#!/usr/bin/env python
#
# Bart Kastermans, www.bartk.nl
#
# rename of collection of files in a directory
import os
import shutil

# only work on files whose name starts with a D
files = [filename for filename in os.listdir ("/Users/kasterma/Music/Audio Hijack/") if filename[0] =="D"]

for filename in files:
    shutil.move (filename, filename [:23] + ".mp3")
share|improve this answer
add comment

mv -i only prompts if the destination exists.

yes n | mv -i … moves all files that don't exist in the destination directory. On FreeBSD and OSX, you can shorten this to mv -n ….

Note that neither of these will merge a directory argument with an existing directory in the same name in the destination directory.


A separate issue is how to act on all the files in the current directory. There are two problems: grabbing all files (* omits dot files) and not running into a command line . On Linux (or more generally with GNU find and GNU coreutils):

find . -mindepth 1 -maxdepth 1 -exec mv -i -t .. -- {} +

With GNU find but not GNU coreutils (or older GNU coreutils):

find . -mindepth 1 -maxdepth 1 -exec sh -c 'mv -i -- "$@" "$0"' .. {} +

Portably:

find . -name . -o -exec sh -c 'mv -i -- "$@" "$0"' .. {} -type d -prune

As usual zsh makes things easier. It doesn't have a command line length limitation internally, so if you use its mv builtin you don't need to worry about that. And you can tell it not to ignore dot files with the D glob qualifier. Limitation: this doesn't work across filesystems (as of zsh 4.3.10).

zmodload zsh/files
mv -i -- *(D) ..
share|improve this answer
    
to many arguments? –  xenoterracide Dec 18 '10 at 12:16
add comment
cp -bal . ..

This will copy everything in the current directory to the directory above it, retaining all permissions, using hardlinks to minimize IO if possible, and on duplicates it creates filename~

after that

rm -rf . ; cd .. ; rmdir <originaldir>;
share|improve this answer
    
probably does run into the large number of files issue... but is not IO intensive as rsync. –  xenoterracide Dec 18 '10 at 12:13
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.