Re: Problem with bash script
Hi, Am Dienstag, 16. Jun 2009, 09:09:09 -0400 schrieb Carmel NY: [...] It seems to work until I get to the copy part where it fails. My scripting skills are not that good. Perhaps someone could tell me what I am doing wrong. # copy the file to another directory using the base name cp $i /usr/home/tmp/$BN Please provide the error message next time. I guess the filenames contain spaces. Try cp $i /usr/home/tmp/$BN Bertram -- Bertram Scharpf Stuttgart, Deutschland/Germany http://www.bertram-scharpf.de ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: Problem with bash script
Hi Carmel On Wed, Jun 17, 2009 at 8:39 AM, Carmel NY carmel...@hotmail.com wrote: I am attempting to write a simple Bash script that will find all the '*.pem' files in a directory structure and move them to another directory. It seems to work until I get to the copy part where it fails. My scripting skills are not that good. Perhaps someone could tell me what I am doing wrong. This is the script: #! /usr/bin/env bash # Save the field separator oIFS=$IFS # Set it to line breaks IFS=$'\n' for i in $(find ./ -name *.pem -print); do # Get the basename BN=$(basename $i) # copy the file to another directory using the base name cp $i /usr/home/tmp/$BN done # Reset the IFS variable IFS=$oIFS exit -- Carmel ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org Why you don't use exec flag of find ? You could use: $ find ./ -name *.pem -exec cp {} /usr/home/tmp/something \; Regards Moises Castellanos ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: Problem with bash script
$ find ./ -name *.pem -exec cp {} /usr/home/tmp/something \; I'm a novice with shell scripting myself, but what's the difference between that code and some variant thereof using a pipe and xargs? Are they simply two different ways of achieving the same result? Or is there some more important difference I may be overlooking? Thanks, Daniel ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: Problem with bash script
On Tue, 16 Jun 2009 15:56:15 +0200 Bertram Scharpf li...@bertram-scharpf.de wrote: Hi, Am Dienstag, 16. Jun 2009, 09:09:09 -0400 schrieb Carmel NY: [...] It seems to work until I get to the copy part where it fails. My scripting skills are not that good. Perhaps someone could tell me what I am doing wrong. # copy the file to another directory using the base name cp $i /usr/home/tmp/$BN Please provide the error message next time. I guess the filenames contain spaces. Try cp $i /usr/home/tmp/$BN Bertram I am an idiot. The problem was that the directory did not exist. It was suppose to be $HOME/tmp/$BN. However, I rarely use find and was not aware of the '-exec' function. I use that and it worked fine. Thanks to everyone for their assistance. -- Carmel ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: Problem with bash script
--On Tuesday, June 16, 2009 08:09:09 -0500 Carmel NY carmel...@hotmail.com wrote: I am attempting to write a simple Bash script that will find all the '*.pem' files in a directory structure and move them to another directory. It seems to work until I get to the copy part where it fails. My scripting skills are not that good. Perhaps someone could tell me what I am doing wrong. This is the script: # ! /usr/bin/env bash # Save the field separator oIFS=$IFS # Set it to line breaks IFS=$'\n' for i in $(find ./ -name *.pem -print); do # Get the basename BN=$(basename $i) # copy the file to another directory using the base name cp $i /usr/home/tmp/$BN done # Reset the IFS variable IFS=$oIFS exit When I write scripts, I test them on the commandline to see if they're doing what I think they're doing. I don't get the $(find ) construction. You're invoking find from within a for loop to return a value. Use backticks. This works. for i in `find ./ -name *.pem -print` do foo bar done -- Paul Schmehl (pa...@utdallas.edu) Senior Information Security Analyst The University of Texas at Dallas http://www.utdallas.edu/ir/security/
Re: Problem with bash script
On Tue, Jun 16, 2009 at 02:33:37PM +, Paul Schmehl wrote: --On Tuesday, June 16, 2009 08:09:09 -0500 Carmel NY carmel...@hotmail.com wrote: I am attempting to write a simple Bash script that will find all the '*.pem' files in a directory structure and move them to another directory. It seems to work until I get to the copy part where it fails. My scripting skills are not that good. Perhaps someone could tell me what I am doing wrong. This is the script: # ! /usr/bin/env bash # Save the field separator oIFS=$IFS # Set it to line breaks IFS=$'\n' for i in $(find ./ -name *.pem -print); do # Get the basename BN=$(basename $i) # copy the file to another directory using the base name cp $i /usr/home/tmp/$BN done # Reset the IFS variable IFS=$oIFS exit When I write scripts, I test them on the commandline to see if they're doing what I think they're doing. I don't get the $(find ) It does exactly the same as `command -a rgs`, but all characters between the parentheses are taken literally (in the backtick form, certain chars have special meaning, but not in the $() form.) construction. You're invoking find from within a for loop to return a value. Use backticks. This works. for i in `find ./ -name *.pem -print` do foo bar done It also works with the $() form, provided the target directory exists! Dan -- Daniel Bye _ ASCII ribbon campaign ( ) - against HTML, vCards and X - proprietary attachments in e-mail / \ pgp7aBx5Ctfjr.pgp Description: PGP signature
Re: Problem with bash script
Carmel NY wrote: I am attempting to write a simple Bash script that will find all the '*.pem' files in a directory structure and move them to another directory. It seems to work until I get to the copy part where it fails. My scripting skills are not that good. Perhaps someone could tell me what I am doing wrong. This is the script: #! /usr/bin/env bash # Save the field separator oIFS=$IFS # Set it to line breaks IFS=$'\n' for i in $(find ./ -name *.pem -print); do # Get the basename BN=$(basename $i) # copy the file to another directory using the base name cp $i /usr/home/tmp/$BN done # Reset the IFS variable IFS=$oIFS exit That's a one-liner: % find . -depth -name '*.pem' -print0 | cpio -0pdmu /usr/home/tmp Actually, that just /copies/ all of the *.pem files to the other directory tree, so if you want to remove the original files, you'ld also need to do: % find . -name '*.pem' -delete once you're sure everything has copied across OK, and with the proviso that '.' is neither a parent or child of /usr/home/tmp Cheers, Matthew -- Dr Matthew J Seaman MA, D.Phil. 7 Priory Courtyard Flat 3 PGP: http://www.infracaninophile.co.uk/pgpkey Ramsgate Kent, CT11 9PW signature.asc Description: OpenPGP digital signature
Re: Problem with bash script
On Tuesday 16 June 2009 06:03:33 Daniel Underwood wrote: $ find ./ -name *.pem -exec cp {} /usr/home/tmp/something \; I'm a novice with shell scripting myself, but what's the difference between that code and some variant thereof using a pipe and xargs? Are they simply two different ways of achieving the same result? Or is there some more important difference I may be overlooking? Moises' way is less efficient as it will copy each file separately, however, if he ends with a + rather then a \;, then using exec is marginally faster as you eliminate 1 pipe from the tool chain. See find(1) for more info. -- Mel ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: Problem with bash script
On Tuesday, June 16, 2009 08:09:09 -0500 Carmel NY carmel...@hotmail.com wrote: C I am attempting to write a simple Bash script that will find all the C '*.pem' files in a directory structure and move them to another C directory. Using find and pax will correctly handle filenames with spaces and other crap. If you use the -depth option in find, you'll also preserve directory modtimes: root# cd /src/directory root# mkdir -p /dest/directory root# find . -depth -print | pax -rwd -pe /dest/directory Use -rwdu if /dest/directory already exists and you don't want to overwrite newer files there with older files from /src/directory. If you want to store the output from pax as an archive file, use the cpio format for the most portability and the least number of limitations on things like pathname size. Another advantage of find vs backquotes is the ability to filter things out of the files being copied: root# find . -depth -print | fgrep -f /files/to/ignore | pax -x cpio -wd | gzip -1c /tmp/src.pax.gz [ archive the pax file, copy it to another system, etc. ] root# cd /dest/directory root# gunzip -c src.pax.gz | pax -r -pe If you have spaces in your filenames and you still want to do some filtering before running xargs, use tr to change newlines to nulls: root# find . -depth -print | /some/filter/here | tr '\012' '\000' | xargs -0 /some/command On Tue, 16 Jun 2009 16:16:26 +0100, Daniel Bye danie...@slightlystrange.org said: D It does exactly the same as `command -a rgs`, but all characters between D the parentheses are taken literally (in the backtick form, certain chars D have special meaning, but not in the $() form.) Either solution will run the command first and then rescan the line in the calling script. You can run into problems when the results of the backquoted command are too big; there's an upper limit to how many arguments you can put in a for loop or pass to a program. Also, any spaces or weird characters in the output are likely to play hell with whatever else you're doing. You're much safer using a pipe. Use backquotes or $() when you're pretty sure the output won't be too big. To be safe, check the argument count when you run something: #!/bin/bash set X `date` # should give 6 tokens plus X. case $# in 1) echo command didn't print anything ;; 7) echo success: $*; echo year should be 7th arg: $7 ;; *) echo something else is wrong ;; esac exit 0 -- Karl Vogel I don't speak for the USAF or my company There is nothing more satisfying than having someone take a shot at you and miss. --Murphy's Laws of Combat ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org
Re: Problem with bash script
I botched the filter example in my previous blathering. This will ignore output from find containing patterns: root# find . -depth -print | fgrep -v -f /some/patterns Leaving off the -v will keep output containing those patterns. -- Karl Vogel I don't speak for the USAF or my company Sign in a Tacoma, Washington men's clothing store: 15 men's wool suits, $10. They won't last an hour! ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to freebsd-questions-unsubscr...@freebsd.org