Unix Programming - mv/cp Only Certain Files

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > November 2005 > mv/cp Only Certain Files





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author mv/cp Only Certain Files
Fao, Sean

2005-11-02, 5:56 pm

Hello,

Is there any easy way to move or copy files *only* if a certain bit
(execute bit, in my case) is set? Basically "mv [all files with execute
bit set] /tmp".

I'm sure I could whip something up in C to read the permissions and then
move them. But I'm guessing that there must be a quick and simple way
to do this in a shell script.

I've done a Google search, but it's kind of a hard topic to search on,
so I haven't come up with anything useful.

Thank you in advance,

--
Sean
Bit Twister

2005-11-02, 5:56 pm

On Wed, 02 Nov 2005 14:01:36 -0500, Fao, Sean wrote:
> Hello,
>
> Is there any easy way to move or copy files *only* if a certain bit
> (execute bit, in my case) is set? Basically "mv [all files with execute
> bit set] /tmp".
>
> I'm sure I could whip something up in C to read the permissions and then
> move them. But I'm guessing that there must be a quick and simple way
> to do this in a shell script.



man find

> I've done a Google search, but it's kind of a hard topic to search on,

http://groups.google.com/advanced_group_search
find perm mv in the first box and
asterisk linux asterisk in the Newsgroup box aught to do it.
Jordan Abel

2005-11-02, 5:56 pm

On 2005-11-02, Fao, Sean <enceladus311@yahoo.comI-WANT-NO-SPAM> wrote:
> Hello,
>
> Is there any easy way to move or copy files *only* if a certain bit
> (execute bit, in my case) is set? Basically "mv [all files with execute
> bit set] /tmp".


find(1) is your friend.

heh - sorry, couldn't say that with a straight face. but still, probably the
best way to do this without hand-coding something in C is to use find.

#find regular files with any execute bit set and move to /tmp
find -type f -mode +0111 -exec mv {} /tmp \;

You should probably check the manpage - in particular, it can be done more
efficiently with + instead of \; on some systems, but not all, and particularly
not gnu. Also check xargs(1).

> I'm sure I could whip something up in C to read the permissions and then
> move them. But I'm guessing that there must be a quick and simple way
> to do this in a shell script.
>
> I've done a Google search, but it's kind of a hard topic to search on,
> so I haven't come up with anything useful.
>
> Thank you in advance,
>

Fao, Sean

2005-11-02, 5:57 pm

Fao, Sean wrote:
> Hello,
>
> Is there any easy way to move or copy files *only* if a certain bit
> (execute bit, in my case) is set? Basically "mv [all files with execute
> bit set] /tmp".


Erg...I feel like such an idiot! I've used find in the way you both
suggested and I knew exactly how to do it, but I was being stupid. Oh
well...

Thank you both very much for your help. I'll attempt to not be such a
dummy in the future!

--
Sean
Ertugrul Soeylemez

2005-11-02, 5:57 pm

LS0tLS1CRUdJTiBQR1AgU0lHTkVEIE1FU1NBR0Ut
LS0tLQ0KSGFzaDogU0hBMQ0KDQpKb3JkYW4g
QWJlbCA8am1hYmVsQHB1cmR1ZS5lZHU+ICgwNS0x
MS0wMiAxOToyMDo1NCk6DQoNCj4gI2ZpbmQg
IHJlZ3VsYXIgZmlsZXMgICB3aXRoIGFueSBleGVj
dXRlIGJpdCBzZXQgICBhbmQgbW92ZSB0byAv
dG1wDQo+IGZpbmQgICAgICAgICAtdHlwZSBmICAg
ICAgICAgICAgICAgIC1tb2RlICswMTExICAg
LWV4ZWMgbXYge30gL3RtcCBcOw0KDQoNCkV2ZW4g
ZWFzaWVyIHZlcnNpb246DQoNCiAgY3AgJChm
aW5kIC10eXBlIGYgLW1vZGUgLi4uKSBERVNUSU5B
VElPTg0KICBtdiAkKGZpbmQgLXR5cGUgZiAt
bW9kZSAuLi4pIERFU1RJTkFUSU9ODQoNCkFzIGFs
cmVhZHkgc2FpZCwgY2hlY2sgb3V0IHRoZSBt
YW5wYWdlIGZvciBob3cgdG8gdXNlIHRoZSAtbW9k
ZSBvcHRpb24uDQoNClJlZ2FyZHMuDQoNCg0K
LSAtLSANCihoa3ApIHN1YmtleXMucGhwLm5ldCAo
bGRhcCkga2V5c2VydmVyLnBncC5jb20gKGh0
dHApIHd3dy5rZXlzZXJ2ZXIuZGUNCklEOiBDRTQw
MjAxMiAoMEYxMiAwOTEyIERGQzggMkZDNSBF
MkI4ICBBMjNFIDZCQUMgOTk4RSBDRTQwIDIwMTIp
DQoNCi0tLS0tQkVHSU4gUEdQIFNJR05BVFVS
RS0tLS0tDQpWZXJzaW9uOiBHbnVQRyB2MS40LjEg
KEdOVS9MaW51eCkNCg0KaUQ4REJRRkRhVXFI
YTZ5WmpzNUFJQklSQXFPQUFLQ2hMVzFTcHRBY0JY
dm4zeGczVXMwNFdkam95d0NhQXQxYw0KQU1R
MGM0SWdjOTI2SXJLN2pDL0xuTjg9DQo9WldMRw0K
LS0tLS1FTkQgUEdQIFNJR05BVFVSRS0tLS0t
DQo=
Chris F.A. Johnson

2005-11-03, 2:50 am

On 2005-11-02, Ertugrul Soeylemez wrote:
>
> Jordan Abel <jmabel@purdue.edu> (05-11-02 19:20:54):
>
>
>
> Even easier version:
>
> cp $(find -type f -mode ...) DESTINATION
> mv $(find -type f -mode ...) DESTINATION


Both of which will fail if any filenames contain spaces.

> As already said, check out the manpage for how to use the -mode option.


The -mode option is non-standard.

--
Chris F.A. Johnson | Author:
<http://cfaj.freeshell.org> | Shell Scripting Recipes:
Any code in this post is released | A Problem-Solution Approach,
under the GNU General Public Licence | 2005, Apress
Ertugrul Soeylemez

2005-11-03, 7:50 am

"Chris F.A. Johnson" <cfajohnson@gmail.com> (05-11-02 23:54:05):

> On 2005-11-02, Ertugrul Soeylemez wrote:
>
> Both of which will fail if any filenames contain spaces.



The former version would fail as well. You have to enclose '{}' in
quotes. At least this version is much faster, because it doesn't call
cp/mv 100 times for 100 files.


>
> The -mode option is non-standard.



I don't even have that option. I'd have used -perm, if I had to do it
with 'find'.

That's why I love zsh. In zsh I'd have done that via normal filename
generation, which also doesn't suffer from the delimiting problem:

# zsh-only: copy all owner-executable files in current directory and
# all subdirectories

cp **/*(#q.*) DESTINATION

Regards.
Jordan Abel

2005-11-03, 5:57 pm

On 2005-11-03, Ertugrul Soeylemez <never@drwxr-xr-x.org> wrote:
> "Chris F.A. Johnson" <cfajohnson@gmail.com> (05-11-02 23:54:05):
>
>
>
> The former version would fail as well. You have to enclose '{}' in
> quotes. At least this version is much faster, because it doesn't call
> cp/mv 100 times for 100 files.


Why do you need to enclose {} in quotes? find doesn't run its -exec arguments
through a shell.

To get even more non-standard, you could -exec mv {} /tmp +

the real "portable" solution is -print0 and xargs
Henry Townsend

2005-11-03, 5:57 pm

Jordan Abel wrote:
> To get even more non-standard, you could -exec mv {} /tmp +


Assuming you refer to the "+" above, it absolutely is standard. It's a
relatively recent addition to SUS and one could argue that it's not
sufficiently portable for that reason. But it *is* standard.

HT
Chris F.A. Johnson

2005-11-03, 5:57 pm

On 2005-11-03, Jordan Abel wrote:
> On 2005-11-03, Ertugrul Soeylemez <never@drwxr-xr-x.org> wrote:
>
> Why do you need to enclose {} in quotes? find doesn't run its -exec arguments
> through a shell.
>
> To get even more non-standard, you could -exec mv {} /tmp +


That IS standard, but not portable; some unices have included it
for a while. GNU has included it recently.

> the real "portable" solution is -print0 and xargs


That is neither standard nor portable.

--
Chris F.A. Johnson | Author:
<http://cfaj.freeshell.org> | Shell Scripting Recipes:
Any code in this post is released | A Problem-Solution Approach,
under the GNU General Public Licence | 2005, Apress
Ertugrul Soeylemez

2005-11-03, 8:49 pm

Jordan Abel <jmabel@purdue.edu> (05-11-03 17:23:13):

> Why do you need to enclose {} in quotes? find doesn't run its -exec
> arguments through a shell.
>
> To get even more non-standard, you could -exec mv {} /tmp +
>
> the real "portable" solution is -print0 and xargs



Sometimes being portable is just not desirable. To be portable you
would need to check the operating system for various properties and
choose the command which best fits it. 100 lines for a simple copy/move
operation. Writing a small portable C program or a script is much
better in this case.

Regards.
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com