LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 04-22-2008, 07:18 PM   #1
jakykong
Member
 
Registered: Apr 2006
Location: Washington
Distribution: Debian Gnu/Linux Lenny on AMD64x2 (32-bit mode), an AMD Sempron 64 laptop, debian, 32bit
Posts: 101

Rep: Reputation: 15
move all files in current directory into a subdirectory in the current directory


What I came up with so far is:
find * .* -maxdepth 0 -path ./new-folder -prune -path ../ -prune -o -exec mv \{\} new-folder \;

Which is intended to move all files and folders, including those beginning with .'s, to the folder new-folder, created in the current directory. Mv alone won't work, because it can't move recursively and doesn't have an option to exclude the new-folder folder from the files it moves.

This *does* work. However, it's really messy, and produces some (seemingly harmless) error messages (although it exits with status 0 on my machine).

Does anyone know of a cleaner way to do this?
 
Old 04-23-2008, 12:28 AM   #2
bgoodr
Member
 
Registered: Dec 2006
Location: Oregon
Distribution: RHEL[567] x86_64, Ubuntu 17.10 x86_64
Posts: 221

Rep: Reputation: 36
Use the -maxdepth 1 option to find, instead of the "*" and ".*", something like this:

Code:
mkdir ./dest_dir
find . -maxdepth 1 | grep -v dest_dir | xargs -i mv {} ./dest_dir
bgoodr
 
Old 04-23-2008, 02:45 AM   #3
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
here's a function i wrote.. i think it's not yet the simplest but i hope it works properly:
Code:
moveallto() {
	local DESTDIR=${1}
	mkdir -p ${DESTDIR}
	find -type d -not -name ${DESTDIR} -not -path "./${DESTDIR}/*" -exec mkdir -p "${DESTDIR}/{}" \;
	find -type f -not -name ${DESTDIR} -not -path "./${DESTDIR}/*" -exec mv '{}' "${DESTDIR}/{}" \;
	find -maxdepth 1 -type d -not -name . -not -name ${DESTDIR} -exec rm -fr {} \;
}

Last edited by konsolebox; 04-23-2008 at 02:47 AM.
 
Old 04-29-2008, 06:04 PM   #4
jakykong
Member
 
Registered: Apr 2006
Location: Washington
Distribution: Debian Gnu/Linux Lenny on AMD64x2 (32-bit mode), an AMD Sempron 64 laptop, debian, 32bit
Posts: 101

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by bgoodr View Post
Use the -maxdepth 1 option to find, instead of the "*" and ".*", something like this:

Code:
mkdir ./dest_dir
find . -maxdepth 1 | grep -v dest_dir | xargs -i mv {} ./dest_dir
bgoodr
I hadn't considered using xargs... Using

find . -maxdepth 1 -exec mv '{}' dest_dir \;

causes an error when find finds the destination directory and tries to move it into itself.

That's definitely a lot easier to read.

Thanks!
 
Old 04-30-2008, 09:58 AM   #5
bgoodr
Member
 
Registered: Dec 2006
Location: Oregon
Distribution: RHEL[567] x86_64, Ubuntu 17.10 x86_64
Posts: 221

Rep: Reputation: 36
Quote:
Originally Posted by jakykong View Post
I hadn't considered using xargs... <snip> 1That's definitely a lot easier to read.
I don't know if it's any easier, my example command is a bit more verbose. However, what I find myself doing a lot is using echo to see what xargs is doing before committing myself to it. So first I add in the echo like this:
Code:
find . -maxdepth 1 | grep -v dest_dir | xargs -i echo mv {} ./dest_dir
The above won't actually mv any files, but will echo out the commands. You can either straight away feed the output to sh like this:
Code:
find . -maxdepth 1 | grep -v dest_dir | xargs -i echo mv {} ./dest_dir | sh -x
(I tacked on the -x to the sh so that I can see each command run such that I can see the command interspersed with any errors that occur in the move). But that isn't very useful in and of itself, but what is useful is maybe doing some sed in between the xargs and the sh.

Oh don't get me started (too late!). Let me warn you about "bad" characters in file names: I have a lot of mp3 files with characters such as spaces, single- and double-quotes. I often want to feed them to tools such as id3v2 to canonicalize the tags. I start out doing something like this:
Code:
find . -name '*.mp3' | xargs -i id3v2 -l {}
which, if you are lucky, gives you a nice error message (xargs on other UNIX's ... well ... maybe not so lucky):
Code:
xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option
Huh? What's that -0 about? It's meant to be used with a command that emits records separated with null codes and not newline codes. The find command by default uses newlines as record separators, but you can change that with the -print0 option (but then it becomes useful only to commands such as xargs that can slurp in output that contains null bytes as the record separator). Using find in that way, and changing xargs to use the -0 option, yields:
Code:
find . -name '*.mp3' -print0 | xargs -0 -i echo id3v2 -l \"{}\"
Oh, and I wrapped double-quotes around the {} and backslashed them. The backslashes are to escape the double-quotes from the shell that I'm typing the command into, so that the eventual shell will not see the single-quotes and get fouled up. And I added the echo so that I could see the commands before committing to them (like I had mentioned earlier). The resulting output on some of my music that had the single quotes and spaces in them looks like this:
Code:
...
id3v2 -l "./The Cars Greatest Hits/10 Let's Go.mp3"
id3v2 -l "./The Cars Greatest Hits/08 My Best Friend's Girl.mp3"
id3v2 -l "./The Cars Greatest Hits/01 Just What I Needed.mp3"
id3v2 -l "./The Cars-All Mixed Up.mp3"
...
then I can tack on the sh along with other filtering like this:
Code:
find . -name '*.mp3' -print0 | xargs -0 -i echo id3v2 -l \"{}\" | sh -x | grep '^TIT2'
resulting in some meaningful output (notice the "+" are from the -x I fed to sh:
Code:
+ id3v2 -l './The Cars Greatest Hits/10 Let'\''s Go.mp3'
TIT2 (Title/songname/content description): Let's Go
+ id3v2 -l './The Cars Greatest Hits/08 My Best Friend'\''s Girl.mp3'
+ id3v2 -l './The Cars Greatest Hits/01 Just What I Needed.mp3'
TIT2 (Title/songname/content description): My Best Friend's Girl
+ id3v2 -l './The Cars-All Mixed Up.mp3'
TIT2 (Title/songname/content description): Just What I Needed
TIT2 (Title/songname/content description): All Mixed Up
The "+" output lines made it past the final grep most likely because the sh command puts those onto standard error and not onto standard output. Notice also that the standard error output is not synchronized with standard output, which puzzles some users.

Whew! Ok I'm done now (I think).

bg
 
1 members found this post helpful.
Old 04-30-2008, 05:35 PM   #6
jakykong
Member
 
Registered: Apr 2006
Location: Washington
Distribution: Debian Gnu/Linux Lenny on AMD64x2 (32-bit mode), an AMD Sempron 64 laptop, debian, 32bit
Posts: 101

Original Poster
Rep: Reputation: 15
That certainly answers quite a few questions about the challenges of shell scripting mass file operations (some questions which I hadn't even considered. Strange filenames is a concern with an archiving script, which would need to reproduce the names faithfully).

Thanks!
 
Old 07-16-2013, 11:50 AM   #7
thomaskirk3
LQ Newbie
 
Registered: Jul 2013
Posts: 1

Rep: Reputation: Disabled
This works for me:

mv *.* sub_dir/
 
Old 07-16-2013, 07:44 PM   #8
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,912

Rep: Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513Reputation: 1513
Just "mv * sub_dir" should do the trick. Now if you have 10s of thousands of files in the working directory it might not. But then you can always do the "mv a* subdir;mv b* subdir..." unless you have 10s of thousands of "a*" files...
 
Old 07-16-2013, 11:46 PM   #9
jdkaye
LQ Guru
 
Registered: Dec 2008
Location: Westgate-on-Sea, Kent, UK
Distribution: Debian Testing Amd64
Posts: 5,465

Rep: Reputation: Disabled
This is a 5 year-old thread. Why bring it back now? The OP is probably long gone.
jdk
 
  


Reply



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 Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
how to find files in current directory only (not recursively) babu198649 Linux - Newbie 2 12-27-2007 01:30 AM
How to untar a file in another directory other then current directory. dr_zayus69 Linux - Software 8 05-16-2007 11:01 AM
script for deleting .dat files which > 5 mb from a directory and its subdirectory anindyabhattacharjee Linux - Enterprise 2 01-15-2007 11:38 PM
How do I produce sorted list of files in current directory over a certain size? bangback Linux - Newbie 3 10-25-2006 12:11 AM
list only files in current directory xscousr Programming 8 09-22-2003 07:35 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 04:05 PM.

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
Open Source Consulting | Domain Registration