LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices



Reply
 
Search this Thread
Old 11-26-2005, 05:46 AM   #1
syssyphus
LQ Newbie
 
Registered: Aug 2005
Posts: 19

Rep: Reputation: 0
xcopy functionality with linux?


I need to do a selective and recursive move. the function I am after is done like this in windows:

xcopy c:\music\*.mp3 d:\music\ /s
del *.mp3 /s


I can probably make a script using find and xargs but I thought I would ask first.

I have looked at mmv and unison, (and rsync) none of those are what I am looking for.

rsync is dooable, but it would copy the files and then delete the source, as opposed to simply moving them (And retaining the original inode)
 
Old 11-26-2005, 06:04 AM   #2
Thoreau
Senior Member
 
Registered: May 2003
Location: /var/log/cabin
Distribution: All
Posts: 1,167

Rep: Reputation: 45
The command to move is mv(move). The command to copy is cp(copy). The command for recursive copying is recursive(-R or -r). The command to delete is rm(remove). The command to delete all subdirectories is force(-f).

cp -R /usr/local/mp3 /home/spackle
mv /usr/local/mp3 /home/spackle
rm -rf /home/spackle/mp3

Last edited by Thoreau; 11-26-2005 at 06:06 AM.
 
Old 11-26-2005, 06:13 AM   #3
syssyphus
LQ Newbie
 
Registered: Aug 2005
Posts: 19

Original Poster
Rep: Reputation: 0
Quote:
Originally posted by Thoreau
The command to move is mv(move). The command to copy is cp(copy). The command for recursive copying is recursive(-R or -r). The command to delete is rm(remove). The command to delete all subdirectories is force(-f).


Thanks, but i already new that much.... you missed the bit about "selective"

say for example i have 10,000 files, and only 1000 end in .txt, how do i *selectively* move those files that end in txt?
 
Old 11-26-2005, 06:28 AM   #4
Thoreau
Senior Member
 
Registered: May 2003
Location: /var/log/cabin
Distribution: All
Posts: 1,167

Rep: Reputation: 45
mv /usr/local/mp3/*.txt /home/spackle/mp3
 
Old 11-26-2005, 06:39 AM   #5
syssyphus
LQ Newbie
 
Registered: Aug 2005
Posts: 19

Original Poster
Rep: Reputation: 0
rofl.... ok now you missed the recursive part....


if i have 100s of sub directories then how do i do it? of course many of those directories will contain the files i want to *selectively* *recursively* move...



{EDIT}

http://www.shellscripts.org/project/mvpartial

i found an answer:

#!/bin/bash

if [ $# -ne 3 ] ; then
echo "Usage:"
echo " $0 <sourcedir> <targetdir> <condition>"
echo " Make sure to put the condition into apostrophes to avoid them"
echo " being interpreted by your shell"
echo
echo "Example:"
echo " $0 /usr/src/foo /usr/src/bar 'baz*'"
echo
exit 1
fi

source=${1%/}
target=${2%/}
regex=$3
if [ ! -d "$source" ] ; then
echo "ERROR: $source is not a directory!"
exit 1
fi
if [ ! -d "$target" ] ; then
echo "ERROR: $target is not a directory!"
exit 1
fi

while read file ; do
dirname=$( dirname "$file" )
dirname=${dirname#${source}/}
mkdir -p "${target}/${dirname}"
mv "${file}" "${target}/${dirname}"
done < <( find "$source" -name "$regex" )

Last edited by syssyphus; 11-26-2005 at 08:03 AM.
 
Old 11-26-2005, 12:51 PM   #6
ioerror
Member
 
Registered: Sep 2005
Location: Old Blighty
Distribution: Slackware, NetBSD
Posts: 536

Rep: Reputation: 30
Quote:
say for example i have 10,000 files, and only 1000 end in .txt, how do i *selectively* move those files that end in txt?
If you used a proper shell like zsh, you could just do

Code:
mv /src/path/**/*.txt /dest/path
No need for any scripts.
 
Old 11-26-2005, 02:58 PM   #7
syssyphus
LQ Newbie
 
Registered: Aug 2005
Posts: 19

Original Poster
Rep: Reputation: 0
oh very nice, thank you... we are almost there =)


the zsh recursive globing works, but if does not retain the original directory hierarchy

example:


[ew@client01]~/raid% find source
source
source/test.txt
source/2ndlevel
source/2ndlevel/test.txt

[ew@client01]~/raid% mv source/**/*.txt dest/
mv: will not overwrite just-created `dest/test.txt' with `source/test.txt'

Last edited by syssyphus; 11-26-2005 at 02:59 PM.
 
Old 11-26-2005, 03:33 PM   #8
ioerror
Member
 
Registered: Sep 2005
Location: Old Blighty
Distribution: Slackware, NetBSD
Posts: 536

Rep: Reputation: 30
Quote:
the zsh recursive globing works, but if does not retain the original directory hierarchy
Aha, what you are looking for is the magic of the zmv function (have a look at /usr/share/zsh/<version>/functions/zmv, it is well documented).

Code:
zmv -p mvmkdir -w '/src/path/**/*.txt' /dest/path/'$1$2'
where mvmkdir is a function/script to ensure that the directory exists:

Code:
mvmkdir() { [[ ! -d $3 ]] && mkdir $3 && mv $@; }
EDIT:

Bugger, ignore the above mvmkdir function -- brain cramp. This should be correct:

Code:
mvmkdir()
{
	local dir=$3:h

	[[ -e $dir && ! -d $dir ]] return 1
	[[ ! -d $dir ]] && mkdir -p $dir
	mv $@
}

Last edited by ioerror; 11-27-2005 at 09:20 AM.
 
Old 11-26-2005, 03:35 PM   #9
Kronocide
LQ Newbie
 
Registered: Nov 2005
Posts: 8

Rep: Reputation: 0
Perl's File::Xcopy is a DOS xcopy on steroids.
http://search.cpan.org/~geotiger/Fil...-0.12/Xcopy.pm
 
Old 11-26-2005, 04:10 PM   #10
DConfusion
LQ Newbie
 
Registered: Nov 2005
Posts: 2

Rep: Reputation: 0
re: xcopy & del ->

Well, close but no cigar so far. I had to test xcopy to see that the 'globbing' (incorrectly from a logic standpoint) did as the original post suggested. The delete command in windows also does the logically fallacious same thing.

To selectively copy, recursively in unix, there is NOT a single hybrid command that accomplishes such. BUT, the beauty of unix is that the toolkit is robust. Break the job into smaller parts.

First, identify the files that need copying.
Then select those files (that is what 'globbing' short-cuts - combining these two issues.)
Then, MOVE them, rather than copying, so that no subsequent 'del' is required.
HOWEVER: The most robust manner to copy files from location A to location B in Unix is the old standby 'tar'.
The most robust manner of identifying files, recursively, is find.
The easiest manner of simulating globbing (ie. wildcard matching) is to use pattern matching - eg. patterns in grep/egrep/fgrep.
(Pattern matching is far more powerful than globbing.)

Avoid globbing with 'thousands of files' and 'hundreds of directories'. Your shell can go belly up. Csh used to have a limit of around 500,000 bytes being matched by globbing, bsh was well over 1,000,000 bytes. Always a difficult limitation to identify, unless one is familiar with it. Not to mention, that 'globbing' that much is extremely slow. Base level unix tools are much more efficient, and tool pattern matching is much more efficient, and flexible than shell globbing.

Method 1:

cd c:/mp3
find . > /tmp/t0
egrep '\.mp3$' /tmp/t0 > /tmp/t1
tar -cf `cat /tmp/t1` | ( cd d:/newdirectory ; tar -xf - )
rm -i /tmp/t0 /tmp/t1 # clean-up one's cruft


# Finished - note - the above is 'overkill' - and ONLY covers the 'xcopy' equiv.
# The detail was provided above so that the following equivs might make sense, as to method.

On one line - the 'xcopy' equiv:

musicfiend> cd c:/mp3 ; tar -cf - `find . | grep '\.[Mm][Pp]3$'` | ( cd d:/newdirectory ; tar -xf - )



On one line - the 'del' equiv (complete with verification of every single file to be removed *s* )

musicfiend> rm -i `find c:/mp3 | grep '\.[Mm][Pp]3$'`



AVOID LIKE THE PLAGUE EVER, EVER, EVER using the 'recursive' flag on rm.

It will eventually nail you, big time. ( The -i flag is overkill - use Method 1 with the file list cat for sure fire safe removal of the files. It gives you a file to be examined first.)

Safer, faster, more precise control in Unix.

Yes, SEEMINGLY more complex, but not really. The 'combining principles' are the same for ALL shells and ALL tools - allowing the same basic 'custom' design to be used for a multitude of solutions and combinations via different tools.

Attitude difference: Tiny tools to build complex, extremely flexible solutions (tar excluded from tiny and uncomplex),
or complex tools with zillions of options, and very specific, inflexible usage.

Just my opinion from the soap box.
 
Old 11-26-2005, 04:21 PM   #11
Kronocide
LQ Newbie
 
Registered: Nov 2005
Posts: 8

Rep: Reputation: 0
Re: re: xcopy & del ->

I just put a short perl wrapper around File::Xcopy in 'xcopy' in /user/local/bin, and now have xcopy for bash.

Quote:
Originally posted by DConfusion
I had to test xcopy to see that the 'globbing' (incorrectly from a logic standpoint) did as the original post suggested. The delete command in windows also does the logically fallacious same thing.
Hmm... I guess I could stick File::DosGlob in there.

*will stop perl advocacy now* :-D
 
Old 11-26-2005, 04:44 PM   #12
DConfusion
LQ Newbie
 
Registered: Nov 2005
Posts: 2

Rep: Reputation: 0
Re: perl advocacy

LOL -

Yes, one can do it that way.

Another Unix axiom - from Larry, I believe.

There is no single right way to do anything in Unix.

I prefer the 'basic' tool kit approach, and really never, ever wish to 'duplicate' dos tools. *w*

Although a perl twinkie myself, some tasks are better done with simplicity. I use perl (started as a bsh script) for an extensive, exhaustive, robust clean up between two semi-duplicated directories. I have never found anything that really comes close to it in dos - and have looked at several dozen so-called 'synchronizing' or 'cleanup' programs. None of them really do the job properly, nor robustly. BUT - the perl script still goes down to the shell tool level for safety (sacrifice some speed). Perl handles all the book keeping, which it does beautifully.

The small tool approach I outlined will work from the command line of even the most basic of installs - ie. a stripped down system. Most of those tools are de rigour in even a base level install.

That said - I like your style, and appreciate the work you have done.
 
Old 11-27-2005, 02:24 PM   #13
eddiebaby1023
Member
 
Registered: May 2005
Posts: 378

Rep: Reputation: 33
To copy selected files use cpio:
Code:
find /blah -name "*.txt" -print | cpio -pvdum /target/dir
You don't have to resort to using an incompatible shell (zsh) to do something this simple.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can I get Ultramon functionality on Linux? Ragueneau Linux - Software 1 09-17-2005 09:53 AM
Windows Alt-ascii number functionality in linux mangolicious Linux - Software 7 06-16-2005 03:32 PM
dos xcopy to backup changes to samba susewho Linux - Software 1 02-01-2005 08:36 AM
L.E.A.P. functionality in linux (as in, what is it?) tcaptain Linux - Wireless Networking 5 12-11-2003 05:19 PM
MS Access-like functionality for Linux? pharaoh Linux - Software 11 11-22-2003 04:36 PM


All times are GMT -5. The time now is 02:45 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration