You are not logged in.
Pages: 1
Hi all,
I don't visit here often, but I glean a lot of good info from reading it. I've
been trying to figure out either a script or even a good one-liner to do
this. I'm troubled (and always have been) about the way ls works with
the -R option. It'll give a file listing with no arguments, but if I try to do
something like "ls -R *.txt", I just get an error saying that no files were
found (and I KNOW there are plenty). It doesn't even list the one in the
home dir. Seems like it's the only switch that does that, and if anyone
knows why, I'd like to know as well!
Anyway, I was going to tidy up my files some, and I wanted to put all of
the PDF files in one place as they are scattered everywhere. I figured if
'ls -R' worked, I might could use cp the same way, but it didn't work as I
had hoped either. I can grep the 'ls -R' output and get all the files, I just
want to consolidate them into one convenient place. What is the best,
cleanest and easiest way to go about this?
Thanks,
G.
Offline
Use find:
find . -type f -name "*.pdf"
Note: replace the . with the path you wish to start looking and know that find is recursive by default
Now that you have a way to find them, combine the find command with the mv command like this and you're done:
find . -type f -name "*.pdf" | xargs -i mv -i {} /path/to/pdfs
Here xargs just takes what the first command finds and does what you tell it...
WARNING: you must be VERY careful as a wrong command can cause massive loss of data!
EDIT: changed the mv to mv -i based on karol's suggestion
Last edited by graysky (2011-06-12 15:46:35)
CPU-optimized Linux-ck packages @ Repo-ck • AUR packages • Zsh and other configs
Offline
find . -name "*.txt"
or something similar should work.
Edit: Yeah, I knew I was right ;P
@ graysky: maybe you can use 'mv -i' so it asks you before overwriting files.
And you can
find . -type f -name "*.pdf" -exec mv -i '{}' /path/to/pdfs \;
Edit 2: LOL! You were faster again :-)
Last edited by karol (2011-06-12 15:48:06)
Offline
@karol - yep both work but the xargs is more efficient than the -exec switch if you care about that.
CPU-optimized Linux-ck packages @ Repo-ck • AUR packages • Zsh and other configs
Offline
xargs isn't more efficient, and its dangerous when used like this. Two options:
1) find -name '*.pdf' -print0 | xargs -0 mv -t /path/to/pdfs
2) find -name '*.pdf' -exec bash 'mv "$@" /path/to/pdfs' _ {} +
Both of these will safely handle filenames with any characters in them
Last edited by falconindy (2011-06-12 16:02:20)
Offline
xargs isn't more efficient, and its dangerous when used like this. Two options:
1) find -print0 | xargs -0
2) find -exec bash 'mv "$@" /path/to/pdfs' _ {} +Both of these will safely handle filenames with any characters in them
Some people say it is / was more efficient
http://www.gnu.org/software/findutils/m … Files.html
http://www.sunmanagers.org/pipermail/su … 06255.html
Offline
falconindy wrote:xargs isn't more efficient, and its dangerous when used like this. Two options:
1) find -print0 | xargs -0
2) find -exec bash 'mv "$@" /path/to/pdfs' _ {} +Both of these will safely handle filenames with any characters in them
Some people say it is / was more efficient
http://www.gnu.org/software/findutils/m … Files.html
http://www.sunmanagers.org/pipermail/su … 06255.html
Your first link talks about 'efficiency' from a sysadmin standpoint -- convenience. Your second link makes the error of not using + with find and launches a new grep for each file. Of course that's going to be slower.
http://mywiki.wooledge.org/UsingFind
Last edited by falconindy (2011-06-12 16:12:18)
Offline
Man, you guys are fast! I kind of figured it would be something like that. I have a
BASH manual (PDF) and just couldn't figure out an EASY way to do this. I can't
believe I didn't think about FIND, that sure made things a lot easier! I've got it now
and intend to keep studying my manual, at least enough so I don't miss things
THIS easy all the time. I had started a script, trying for and if and just all kinds of
different ways. That's the number one good thing about Linux, there's always a
way to do it, and often several.
Thanks, you guys. I feel so miserable now, as that seemed like such a stupid
question. I'm grateful that I got any response at all, but you guys went above and
beyond to help out, and it works beautifully no matter which version you use. At
first, I changed the 'mv' to a 'cp', just in case. I saw that worked, so I deleted all the
files in my /pdfs DIR and changed the 'cp' back to 'mv'. Thanks again, and I still feel
ignorant as this would not have been a problem had I remembered 'FIND'!
And the command file I was coming up with.. well let's just say it wasn't coming
along too well. I did the 'ls -R' (still don't get that one!), redirected to a file, and
was considering reading that and then copying/moving the file names within.
Needless to say, this was getting to be a long, drawn-out process. That's why I
broke down and posted.
Thanks again,
G.
Last edited by gmorris (2011-06-12 17:26:56)
Offline
For future use you might want to look at "globbing".
zsh for example will expand the double star **/ to all subfolders. So instead of "find -name '*.pdf' -exec bash 'mv "$@" /path/to/pdfs' _ {} +" you would write "mv **/*.pdf /path". I'm not sure how bash does it but it should be similar or even equal.
chris@chrisl ~/test % touch test/test/foo.txt
chris@chrisl ~/test % touch test/test/bar.txt
chris@chrisl ~/test % mv **/*.txt .
chris@chrisl ~/test % ls
bar.txt foo.txt test/
chris@chrisl ~/test %
Last edited by Cdh (2011-06-12 20:00:18)
฿ 18PRsqbZCrwPUrVnJe1BZvza7bwSDbpxZz
Offline
For future use you might want to look at "globbing".
zsh for example will expand the double star **/ to all subfolders. So instead of "find -name '*.pdf' -exec bash 'mv "$@" /path/to/pdfs' _ {} +" you would write "mv **/*.pdf /path".
chris@chrisl ~/test % touch test/test/foo.txt chris@chrisl ~/test % touch test/test/bar.txt chris@chrisl ~/test % mv **/*.txt . chris@chrisl ~/test % ls bar.txt foo.txt test/ chris@chrisl ~/test %
No, wait, bash (IIRC bash4) can totally do this too ;P You just need to add 'shopt -s globstar' to your .bashrc.
Offline
I just use prompt# ls -lsaR *
Ofcourse, you can 'alias' that in your .aliases (example: alias lr='ls -lsaR' )
Offline
Pages: 1